You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

hls.js携带Authorization请求头访问DigitalOcean Spaces报CORS错误

问题原因

这个CORS报错逻辑非常明确:你当前配置的xhrSetup是全局生效规则,会给hls.js发出的所有请求统一加上withCredentials: true和自定义Authorization头——这些请求不止打向你的Laravel后端/stream接口,还包括后续拉取DigitalOcean(DO) Spaces上的二级m3u8文件、ts音频分片的请求。
但DO Spaces默认CORS策略不接受带身份凭证的请求,也不会放行带自定义Authorization头的预检请求,所以请求打到存储桶时直接被浏览器跨域策略拦截。
本地MinIO能正常运行,是因为你自行给MinIO配置了放开权限的CORS规则;删掉xhrSetup配置后DO Spaces能访问,是因为不带自定义头、不带凭证的普通GET请求,本来就在DO默认CORS允许范围内。

最优解决方案(生产可用,符合鉴权要求)

不要让前端给DO Spaces的请求携带鉴权头,改用后端生成临时签名URL的方式实现鉴权,从根源上绕开跨域问题,安全性也更高:

  1. 先配置DO Spaces的CORS规则(在DO控制台对应存储桶的设置页找到CORS配置项):
    • 允许来源:填写前端实际访问地址,本地开发填http://127.0.0.1:8080,生产环境填线上域名,不要用*通配
    • 允许方法:仅开启GET
    • 允许头:留空使用默认值即可
    • 允许凭证:关闭,不需要开启
  2. 改造Laravel端的/songs/{id}/stream接口逻辑:
    • 接口首先校验请求携带的Bearer令牌合法性,确认用户有对应音频的访问权限
    • 权限校验通过后,不要直接返回存储了DO公网固定地址的m3u8内容。先读取原m3u8文件内容,把里面所有DO资源路径(包括二级m3u8、所有ts分片地址)全部替换成DO Spaces生成的临时签名URL
    • DO Spaces兼容S3协议,使用官方SDK即可生成自定义有效期的临时签名URL,比如设置1小时有效期,过期后URL自动失效,无权限用户根本拿不到有效地址,完全满足鉴权要求
    • 将替换完路径的m3u8内容作为接口响应返回给前端
  3. 调整前端hls.js配置,取消全局加鉴权头的逻辑,仅在请求自有后端接口时携带令牌,修改后代码如下:
const audio = document.querySelector("#player");
this.player = new Plyr(audio, {
    controls: ["play", "progress", "current-time", "mute", "volume"],
});
if (Hls.isSupported()) {
    const token = localStorage.getItem("auth-token");
    this.hls = new Hls({
        debug: true,
        enableWorker: true,
        lowLatencyMode: true,
        backBufferLength: 90,
        xhrSetup: (xhr, url) => {
            // 仅请求自有后端接口时携带鉴权头
            if (url.startsWith(process.env.VUE_APP_API_ENDPOINT)) {
                xhr.setRequestHeader("Authorization", "Bearer " + token);
                // 如果后端不需要cookie跨域传递,这行可以直接删除
                // xhr.withCredentials = true;
            }
            // 请求DO Spaces资源时走默认逻辑,不携带任何自定义头
        },
    });
    this.hls.loadSource(`${process.env.VUE_APP_API_ENDPOINT}/songs/${this.currentSong.id}/stream`);
    this.hls.attachMedia(audio);
    if (this.play) {
        this.player.play();
    }
}

这个方案无兼容性问题,鉴权逻辑全部收归后端控制,不会出现资源泄露,也完全符合DO Spaces的安全规则。

临时测试方案(不建议生产环境使用)

如果只是本地调试临时跑通流程,一定要让前端直接带Authorization头请求DO Spaces,可以手动修改DO控制台存储桶的CORS规则:

  • 允许来源:必须明确填写前端域名,绝对不能用*(带凭证的请求不支持通配来源)
  • 允许方法:开启GET、OPTIONS
  • 允许头:添加Authorization
  • 允许凭证:开启Access-Control-Allow-Credentials开关
  • 暴露头:添加Content-Length, Content-Type
    但这个方案没有实际鉴权效果——DO Spaces本身不会校验你传递的Bearer令牌,任何人拿到资源公网地址就能直接访问,等于鉴权逻辑完全失效,生产环境不要使用这种配置。

内容的提问来源于stack exchange,提问作者Debarshi Das

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 20:09:35