1598 字
8 分钟

解决openlist对象储存403报错

2025-05-15
浏览量 加载中...

前不久给自己的OSS图床开启了防盗链,限制只有自己的网站才能访问,结果一打开OpenList,发现里面的图片全都挂了。

明明已经把自己的子域名加进白名单了,为什么还是被拦截?折腾了一番后总算解决了,记录一下整个排查过程。

一、排查原因:请求没有携带Referer#

打开OpenList网盘页面,进入开发者工具在Network中刷新页面,找到加载失败的图片请求。

查看响应信息,发现返回的是403 Forbidden,第一反应就是OSS防盗链拦截了请求。

但有点奇怪,我明明已经把自己的子域名加入了白名单,按理说不应该被拦截才对。

继续检查请求头,发现问题所在:请求里根本没有Referer字段。

而我的OSS防盗链设置恰好是不允许空Referer访问,所以请求直接被拒绝了。

接着检查OpenList页面,发现HTML的头部有这样一行配置:

<meta name="referrer" content="same-origin">

问题就出在这里。

虽然网盘和图床都属于同一个主域zwfpro.com,但它们并不是同一个Origin(源)。same-origin策略只会在同源请求中发送Referer,跨子域请求则不会携带。

所以,即使OSS白名单配置正确,还是会因为请求没有Referer而返回403。

二、尝试方案一:在自定义头部添加meta标签(无效)#

既然找到了原因,第一个想到的就是OpenList后台自带的「自定义头部」功能。

于是直接添加了新的Referer策略:

<meta name="referrer" content="strict-origin-when-cross-origin">

保存后刷新页面,图片依旧加载失败。

重新检查页面,发现原来的same-origin和新添加的策略同时存在,并没有替换掉原来的标签。

看来这个方法行不通,继续折腾。

三、尝试方案二:通过自定义内容注入JavaScript(无效)#

后台还有一个「自定义内容」功能,可以插入HTML和JavaScript。于是又尝试通过脚本修改原来的标签:

<script>
(function () {
var meta = document.querySelector('meta[name="referrer"]');
if (meta) {
meta.setAttribute('content', 'strict-origin-when-cross-origin');
}
})();
</script>

思路很简单:找到原来的meta标签,直接修改它的content属性。

但实际测试后,图片还是403。问题在于,这种方式无法保证脚本执行时图片请求还没有发出,单纯修改标签也不能保证首次请求就使用新的策略。

连续试了两种方法都没成功,只能换个思路。

四、最终方案:使用外置前端资源#

难道只能修改OpenList前端源码,再重新编译整个二进制文件?

其实没必要这么麻烦,查看OpenList官方文档后,发现可以通过data/config.json中的dist_dir配置指定前端资源目录。也就是说,可以单独修改前端文件,让OpenList加载修改后的资源,不需要重新编译后端。

1. 确认OpenList版本#

先进入OpenList安装目录,查看当前版本:

Terminal window
./openlist version

我的版本是v4.2.6,因此后续下载的前端资源也选择对应版本,避免前后端版本不一致。

2. 下载对应版本的前端资源#

前往OpenList-Frontend官方发布页面:

OpenList-Frontend Releases

找到与当前OpenList版本对应的发布包。这里我选择的是标准版openlist-frontend-dist-v4.2.6.tar.gz,而不是Lite精简版,尽量避免前端功能差异。

3. 解压并修改前端文件#

在OpenList安装目录下的data文件夹中创建dist目录,将下载的前端压缩包解压进去。

目录结构需要注意,确保index.html直接位于dist目录中,而不是多嵌套一层文件夹。例如:

/openlist安装目录/
├── openlist
└── data/
├── config.json
└── dist/
├── index.html
└── 其他前端资源

接着编辑data/dist/index.html,找到原来的标签:

<meta name="referrer" content="same-origin" />

将其修改为:

<meta name="referrer" content="strict-origin-when-cross-origin" />

这样,HTTPS页面请求HTTPS图片时,浏览器就可以发送来源站点的Referer,而不会附带完整的页面路径和查询参数。

4. 修改OpenList配置#

打开安装目录下的data/config.json,找到 dist_dir 配置项。

原来的配置是:

"dist_dir": ""

修改为实际的前端资源目录:

"dist_dir": "/openlist安装目录/data/dist"

这里填写的是服务器上的绝对路径,需要根据自己的实际安装目录修改。其他配置保持不变即可。

5. 重启OpenList#

保存配置后,执行:

Terminal window
systemctl restart openlist

重启完成后,浏览器按Ctrl + F5强制刷新页面。

6. 验证修改是否生效#

重启后不要急着判断是否成功,先确认OpenList是否真的加载了修改后的前端文件。

第一步:检查页面源码

确认原来的:

<meta name="referrer" content="same-origin" />

已经变成:

<meta name="referrer" content="strict-origin-when-cross-origin" />

如果仍然是same-origin,说明修改后的前端资源可能没有生效。可以检查dist_dir路径是否正确,并清除浏览器缓存后重试。

第二步:检查图片请求

打开开发者工具,进入Network,重新加载页面,找到加载失败的图片请求,查看请求头。

确认请求中已经出现:

Referer: https://img.xxx.com/

且图片请求的响应状态码应该由403 Forbidden变为200 OK

确认页面源码和请求头都正常后,基本就可以确定这次修改已经生效,至此,图片终于正常显示了。

如果Referer已经出现,但图片仍然返回403,就需要继续检查OSS防盗链白名单、黑名单及其他访问规则。

最后#

这次问题其实不复杂,根源就是same-origin策略导致跨子域图片请求没有携带Referer。

前面两种方法没成功,主要是因为追加标签并不能替换原有策略,而注入脚本又存在执行时机的问题。最后通过dist_dir使用外置前端资源,只修改一个HTML标签就解决了,不用动后端二进制文件。

如果以后升级OpenList,需要留意前后端版本是否匹配,以及外置前端资源是否需要同步更新。

如果不再需要外置前端,也可以将dist_dir恢复为空字符串,让程序使用内置资源。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

解决openlist对象储存403报错
https://blog.zwfpro.com/posts/oplist-oss/
作者
赵公子
发布于
2025-05-15
许可协议
CC BY-NC-SA 4.0
最后更新于 2025-05-15,距今已过 524 天

部分内容可能已过时

评论区

Profile Image of the Author
赵公子
所见皆可记,所遇皆有意
公告
欢迎来到岁语集,这里是赵公子的博客,记录技术、生活与思考。
分类
标签
站点统计
文章
14
分类
7
标签
24
总字数
6,151
运行时长
0 天
最后活动
0 天前

目录