尝试解决本文中提到的问题:https://philna.sh/blog/2018/10/23/service-workers-beware-safaris-range-request/ 和这里: PWA - cached video will not play in Mobile Safari (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也显示类型:“ opaque”,也许与它有关吗?不太确定接下来要看什么。如果我们无法解决Chrome的问题,则可能需要针对Safari的其他解决方案。
答案 0 :(得分:0)
看来这是不透明的反应。我没有意识到默认情况下访存是“ nocors”。添加“ cors”模式并覆盖range标头似乎允许重写在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: *