我正在尝试将服务工作者集成到我的应用程序中,但我发现服务工作者即使在线也尝试检索缓存内容,但我希望它在这些情况下更喜欢网络。我怎样才能做到这一点?下面是我现在的代码,但我认为它不起作用。为简洁起见,省略了SW安装代码。
var CACHE_NAME = 'my-cache-v1';
var urlsToCache = [
/* my cached file list */
];
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
/* request is being made */
self.addEventListener('fetch', function(event) {
event.respondWith(
//first try to run the request normally
fetch(event.request).catch(function() {
//catch errors by attempting to match in cache
return caches.match(event.request).then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
});
})
);
});
这似乎导致像The FetchEvent for "[url]" resulted in a network error response: an object that was not a Response was passed to respondWith().
这样的警告,我是服务工作者的新手,所以对任何错误的术语或不良做法表示道歉,欢迎任何提示。谢谢!
答案 0 :(得分:10)
如果不对此进行测试,我的猜测是,在没有缓存匹配的情况下,您没有正确解析respondWith()
。 According to MDN,传递给respondWith()
的代码应该“通过将响应或网络错误返回到Fetch来解决”。那么为什么不尝试这样做:
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request).catch(function() {
return caches.match(event.request);
})
);
});
答案 1 :(得分:5)
为什么不打开fetch事件的缓存? 我认为服务工作者的过程是:
打开缓存
检查请求是否与缓存中的答案匹配
然后你回答
OR(如果答案不在缓存中):
通过网络检查请求
从网络克隆答案
将请求和克隆的答案放在缓存中以备将来使用
我会写:
self.addEventListener('fetch', event => {
event.respondWith(
caches.open(CACHE_NAME).then(cache => {
return cache.match(event.request).then(response => {
return response || fetch(event.request)
.then(response => {
const responseClone = response.clone();
cache.put(event.request, responseClone);
})
})
}
);
});
答案 2 :(得分:2)
event.respondWith() expects a promise that resolves to Response。因此,如果发生高速缓存未命中的情况,您仍然需要返回响应,但是在上面,您什么也不返回。我也将尝试先使用缓存,然后再获取,但是无论如何,作为最后的选择,您始终可以创建合成的Response,例如:
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: activemq
namespace: dev
labels:
app: activemq
spec:
replicas: 1
serviceName: activemq-svc
selector:
matchLabels:
app: activemq
template:
metadata:
labels:
app: activemq
spec:
securityContext:
runAsUser: 1000
fsGroup: 2000
runAsNonRoot: false
containers:
- name: activemq
image: "mydocker/amq:latest"
imagePullPolicy: "Always"
ports:
- containerPort: 61616
name: port-61616
- containerPort: 8161
name: port-8161
volumeMounts:
- name: activemq-data
mountPath: "/opt/activemq/data"
restartPolicy: Always
imagePullSecrets:
- name: regsecret
tolerations:
- effect: NoExecute
key: appstype
operator: Equal
value: ibd-mq
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: appstype
operator: In
values:
- dev-mq
volumeClaimTemplates:
- metadata:
name: activemq-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: "gp2-us-east-2a"
resources:
requests:
storage: 100Gi