代码之家  ›  专栏  ›  技术社区  ›  Uriah Blatherwick Jeremy Powell

无法按rangerequest访问arraybuffer

  •  0
  • Uriah Blatherwick Jeremy Powell  · 技术社区  · 7 年前

    试图解决本文中提到的问题: 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上显示视频。文章说,它已经解决了这个问题,但似乎造成了另一个问题的铬。我们解决方案的一个不同之处在于我们没有使用缓存。目前我们只想在我们的服务人员中传递请求。实现如下:

    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显示的是类型:“不透明”所以这可能与它有关?不太清楚下一步该看什么。如果我们不能解决Chrome的问题,我可能需要一个不同的Safari解决方案。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Uriah Blatherwick Jeremy Powell    7 年前

    这似乎是一种不透明的反应。我没有意识到默认情况下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: *