Ghost不能加载URL嵌入资源

这个功能貌似叫oembed。简单来说就是当我在嵌入Youtube链接时,不能显示视频预览框,只能纯url显示。

问题提自这里,原因也提了:

没有灵魂的滑板真好玩-周末河边浪
玩电动滑板甩了一跤,差点与世长辞。 3月的天气很暖和,桃树已经开花了,但是地还没有绿。 躺下看会书。 自己建的书库也用上了,啊,舒服。 Blobolb | Shelf: ‘本站自用,有朋 + Discord (@gvhi)’发现数千本精彩电子书,涵盖各种题材,从小说到自助书籍一应俱全。免费浏览和下载你喜爱的电子书,随时随地畅享阅读乐趣!BlobolbMatthew McConaughey 一小段视频福利 https://www.youtube.com/watch?v=ytjm2Y5nSGo&ab_channel=ChickChicken 这个链接竟然不能以漂亮的缩略图形式显示,类似下面这样。 使用Raspberry pi 搭建Ghost博客(docker)盆友,你猜的没错,本站用的博客就跑在树莓派上。 图样图森破: 看到没,刚创建5小时就迫不及待的发First Post,吼吼吼。 print(“Hello World!

思路

Ghost放在大局域网内。

使用Raspberry pi 搭建Ghost博客(docker)
盆友,你猜的没错,本站用的博客就跑在树莓派上。 图样图森破: 看到没,刚创建5小时就迫不及待的发First Post,吼吼吼。 print(“Hello World!”) docker和mysql的安装就不说了,直接上 docker-compose.yml version: ‘3.1’ services: ghost: container_name: ghost image: ghost:latest restart: always ports: - 2368:2368 environment: # 更改mysql连接信息 (我用的mysql早就装在了nas机器上) database__client: mysql database__connection__host: mysql_ip database__connection__user: db_user database__connection_

就是因为我的Ghost所在Docker不能访问Youtube导致,应该只要翻个墙就好了。

解决方法

在原有docker-compose.yml加入如下内容

  HTTP_PROXY: http://host.docker.internal:3129
  HTTPS_PROXY: http://host.docker.internal:3129

  extra_hosts:
    - "host.docker.internal:host-gateway"

3129端口是树莓派上已弄好http代理口。

进入Ghost命令行,使用curl测试代理,确保代理成功。

到这里,我迫不及待测试了一下Ghost。

有没有搞错,还是不行啊。

经过短暂思索,大致想到了原因。因为Ghost用node写的,linux中虽然很多程序会利用环境变量,像curl,wget。但是node发送http的请求的库不一定会用系统环境变量,一般都是程序里显式写proxy。

想到这一层就简单了。首先找到Ghost发送请求的代码,然后在代码中加入类似proxy参数。

进入Ghost命令行

docker exec -it 58ccb24d9e02 /bin/bash

当我访问网页时,发现有一个接口报错,里面包含oembed字样。那就先以这个关键字搜索代码目录。

grep -rl "oembed" .   # /var/lib/ghost/current

看名字翻找几个就找了,文件路径 ./node_modules/@tryghost/oembed-service/lib/OEmbedService.js

    /**
     * @param {string} url
     */
    async knownProvider(url) {
        const {extract} = require('@extractus/oembed-extractor');

        try {
            return await extract(url);
        } catch (err) {
            if (err.message === 'Request failed with error code 401') {
                throw new errors.UnauthorizedError({
                    message: messages.unauthorized
                });
            } else {
                throw new errors.InternalServerError({
                    message: err.message
                });
            }
        }
    }

贴上这个库github项目地址

GitHub - extractus/oembed-extractor: Extract oEmbed data from given webpage
Extract oEmbed data from given webpage. Contribute to extractus/oembed-extractor development by creating an account on GitHub.

作者还贴心的在Readme里写了proxy的用法。

最终更改如下

    /**
     * @param {string} url
     */
    async knownProvider(url) {
        const {extract} = require('@extractus/oembed-extractor');
         const {HttpsProxyAgent} = require('https-proxy-agent');

        try {
            return await extract(url, null, {
                    agent: new HttpsProxyAgent("http://host.docker.internal:3129"),
            });
        } catch (err) {
            if (err.message === 'Request failed with error code 401') {
                throw new errors.UnauthorizedError({
                    message: messages.unauthorized
                });
            } else {
                throw new errors.InternalServerError({
                    message: err.message
                });
            }
        }
    }

问题解决(看图)。

Ghost日志

如果有谁能在Ghost后台管理界面加上Proxy配置选项就完美了。