google-chrome - 无法访问 RangeRequest 上的 arrayBuffer
问题描述
试图解决本文中提到的问题:https ://philna.sh/blog/2018/10/23/service-workers-beware-safaris-range-request/ 和这里: PWA - 缓存的视频不会在移动设备中播放野生动物园 (11.4)
根本问题是我们无法在 Safari 上显示视频。这篇文章说它已经解决了这个问题,但似乎在 Chrome 上引起了另一个问题。我们解决方案的不同之处在于我们没有使用缓存。目前我们只想在我们的服务工作者中传递请求。实现如下所示:
self.addEventListener('fetch', function (event){
if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') {
return;
}
if (event.request.headers.get('range')) {
event.respondWith(returnRangeRequest(event.request));
} else {
event.respondWith(fetch(event.request));
}
});
function returnRangeRequest(request) {
return fetch(request)
.then(res => {
return res.arrayBuffer();
})
.then(function(arrayBuffer) {
var bytes = /^bytes\=(\d+)\-(\d+)?$/g.exec(
request.headers.get('range')
);
if (bytes) {
var start = Number(bytes[1]);
var end = Number(bytes[2]) || arrayBuffer.byteLength - 1;
return new Response(arrayBuffer.slice(start, end + 1), {
status: 206,
statusText: 'Partial Content',
headers: [
['Content-Range', `bytes ${start}-${end}/${arrayBuffer.byteLength}`]
]
});
} else {
return new Response(null, {
status: 416,
statusText: 'Range Not Satisfiable',
headers: [['Content-Range', `*/${arrayBuffer.byteLength}`]]
});
}
});
}
我们确实在范围请求获取时返回了一个数组缓冲区,但它的 byteLength 为零并且似乎是空的。范围标头实际上包含“bytes=0-”,后续请求有一个开始值,但没有结束值。
也许我们可以做一些特征检测来确定它是 chrome 并且我们可以定期调用 fetch ?我宁愿有一个适用于任何地方的解决方案。res 也显示 type:"opaque" 所以也许这与它有关?不太确定接下来要看什么。如果我们不能解决 Chrome 的问题,我可能需要 Safari 的不同解决方案。
解决方案
似乎这是不透明的反应。我没有意识到 fetch 默认是“nocors”。添加“cors”模式并覆盖范围标题似乎允许重写在 chrome 上工作。可悲的是,它仍然无法在 Safari 上运行,但我能够在正确设置 cors 值后访问 arrayBuffer。
这是我必须做出的改变:
var myHeaders = {};
return fetch(request, { headers: myHeaders, mode: 'cors', credentials: 'omit' })
.then(res => {
return res.arrayBuffer();
})
服务器使用允许的标头进行响应很重要。例如
access-control-allow-methods: GET
access-control-allow-origin: *
推荐阅读
- ruby-on-rails - 从另一台设备观看本地网络上的 puma 输出
- python - 如何遍历基因/ URL 列表并生成基因信息行?
- python - 为什么要在 Numpy 中初始化一个数组
- java - java中的Calendar.getInstance().get(Calendar.DAY_OF_WEEK)和Calander.DAY_OF_WEEK有什么区别
- mysql - MySQL 一行仅选择没有 NULL 值的列
- javascript - 我的 Node.js 上传到 Heroku 后没有发送邮件
- graphics - 3D 光线投射算法中的光线遍历
- numpy - 如何使用 pcolormesh 绘制自定义频谱图
- javascript - 我们如何使用 Google Drive Picker API 包含用户拥有并与用户共享的所有文件?
- javascript - React useState 设置状态原因