无法访问RangeRequest上的arrayBuffer [英] Can't access arrayBuffer on RangeRequest

查看:37
本文介绍了无法访问RangeRequest上的arrayBuffer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试解决本文中提到的问题: PWA-缓存的视频将无法在Mobile Safari中播放(11.4)

Trying to solve the problem referenced in this article: https://philna.sh/blog/2018/10/23/service-workers-beware-safaris-range-request/ and here: PWA - cached video will not play in Mobile Safari (11.4)

根本问题是我们无法在Safari上显示视频.这篇文章说它已经解决了这个问题,但似乎在Chrome上引起了另一个问题.解决方案的不同之处在于,我们没有使用缓存.目前,我们只想在我们的服务人员中传递请求.实现看起来像这样:

The root problem is that we aren't able to show videos on Safari. The article says it has the fix for the issue but seems to cause another problem on Chrome. A difference in our solution is that we aren't using caching. Currently we just want to pass through the request in our service worker. Implementation looks like this:

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-",随后的请求有一个开始值,但没有结束值.

We do get an array buffer returned on the range request fetch but it has a byteLength of zero and appears to be empty. The range header actually contains "bytes=0-" and subsequent requests have a start value but no end value.

也许我们可以做一些特征检测来确定它是chrome,我们可以定期调用fetch吗?我宁愿有一个在任何地方都可以使用的解决方案.res也显示类型:"opaque",也许与它有关吗?不太确定接下来要看什么.如果我们无法解决Chrome的问题,则可能需要针对Safari的其他解决方案.

Maybe there is some feature detection we can do to determine that it's chrome and we can just call fetch regularly? I'd rather have a solution that works everywhere though. Also res is showing type:"opaque" so maybe that has something to do with it? Not quite sure what to look at next. If we can't solve the problem for Chrome I might need a different solution for Safari.

推荐答案

似乎是不透明的响应.我没有意识到默认情况下访存是"nocors".添加"cors"模式并覆盖范围标头似乎已允许重写在chrome上进行.不幸的是,它仍然无法在Safari上运行,但是在正确设置cors值后,我能够访问arrayBuffer.

It seems that it was the opaque response. I didn't realize that fetch was 'nocors' by default. Adding 'cors' mode and overwriting the range header seems to have allowed the rewrite to work on chrome. Sadly, it still doesn't work on Safari, but I was able to access the arrayBuffer after setting the cors values properly.

这是我必须进行的更改:

Here is the change I had to make:

var myHeaders = {};
return fetch(request, { headers: myHeaders, mode: 'cors', credentials: 'omit' })
    .then(res => {
        return res.arrayBuffer();
    })

服务器使用允许的标头进行响应很重要.例如

It's important that the server respond with allowed headers. e.g.

access-control-allow-methods: GET
access-control-allow-origin: *

这篇关于无法访问RangeRequest上的arrayBuffer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆