考虑这个示例 index.html
文件。
<!DOCTYPE html>
<html><head><title>test page</title>
<script>navigator.serviceWorker.register('sw.js');</script>
</head>
<body>
<p>test page</p>
</body>
</html>
使用此 Service Worker,旨在从缓存加载,然后在必要时回退到网络。
cacheFirst = (request) => {
var mycache;
return caches.open('mycache')
.then(cache => {
mycache = cache;
cache.match(request);
})
.then(match => match || fetch(request, {credentials: 'include'}))
.then(response => {
mycache.put(request, response.clone());
return response;
})
}
addEventListener('fetch', event => event.respondWith(cacheFirst(event.request)));
这在 Chrome 62 上严重失败。刷新 HTML 根本无法在浏览器中加载,并出现“无法访问此站点”错误;我必须转移刷新才能摆脱这种 splinter 的状态。在控制台中,它说:
Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'ServiceWorkerGlobalScope': Cannot construct a Request with a Request whose mode is 'navigate' and a non-empty RequestInit.
“构造一个请求”?!我不是在构建请求。我正在使用事件的请求,未修改。我在这里做错了什么?
最佳答案
根据进一步的研究,事实证明我正在在我fetch(request, {credentials: 'include'})
时构造一个请求!
每当您将选项对象传递给 fetch
时,该对象就是 RequestInit
,当您这样做时它会创建一个新的 Request
对象.而且,呃,显然你不能要求 fetch()
在 navigate
模式下创建一个新的 Request
和一个非空的 RequestInit
出于某种原因。
在我的例子中,事件的导航 Request
已经允许凭据,所以修复是将 fetch(request, {credentials: 'include'})
转换为 获取(请求)
。
由于 this Google documentation article,我误以为我需要 {credentials: 'include'}
.
When you use fetch, by default, requests won't contain credentials such as cookies. If you want credentials, instead call:
fetch(url, { credentials: 'include' })
只有在您传递获取 URL 时才会如此,就像他们在代码示例中所做的那样。如果你手头有一个 Request
对象,就像我们通常在 Service Worker 中做的那样,Request
知道它是否想要使用凭据,所以 fetch( request)
将正常使用凭据。
关于javascript - 无法使用模式为 'navigate' 和非空 RequestInit 的 Request 构造 Request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46982502/