[英]Can service workers cache POST requests?
我嘗試在fetch事件中緩存服務工作者的POST請求。
我使用了cache.put(event.request, response)
,但返回的promise被TypeError: Invalid request method POST.
拒絕TypeError: Invalid request method POST.
。
當我嘗試使用相同的POST API時, caches.match(event.request)
給了我undefined。
但是當我為GET方法做同樣的事情時,它起作用了:對於GET請求的caches.match(event.request)
給了我一個響應。
服務工作者可以緩存POST請求嗎? 如果他們不能,我們可以使用什么方法使應用程序真正脫機?
您無法使用Cache API緩存POST請求。 請參閱https://w3c.github.io/ServiceWorker/#cache-put (第4點)。
在規范庫中有一個相關的討論: https : //github.com/slightlyoff/ServiceWorker/issues/693
一個有趣的解決方案是ServiceWorker Cookbook中提供的解決方案: https : //serviceworke.rs/request-deferrer.html基本上,該解決方案將請求序列化到IndexedDB。
我在最近使用GraphQL API的項目中使用了以下解決方案:我使用Request as cache cache key的序列化表示來緩存IndexedDB對象存儲中API路由的所有響應。 然后,如果網絡不可用,我使用緩存作為后備:
// ServiceWorker.js
self.addEventListener('fetch', function(event) {
// We will cache all POST requests to matching URLs
if(event.request.method === "POST" || event.request.url.href.match(/*...*/)){
event.respondWith(
// First try to fetch the request from the server
fetch(event.request.clone())
// If it works, put the response into IndexedDB
.then(function(response) {
// Compute a unique key for the POST request
var key = getPostId(request);
// Create a cache entry
var entry = {
key: key,
response: serializeResponse(response),
timestamp: Date.now()
};
/* ... save entry to IndexedDB ... */
// Return the (fresh) response
return response;
})
.catch(function() {
// If it does not work, return the cached response. If the cache does not
// contain a response for our request, it will give us a 503-response
var key = getPostId(request);
var cachedResponse = /* query IndexedDB using the key */;
return response;
})
);
}
})
function getPostId(request) {
/* ... compute a unique key for the request incl. it's body: e.g. serialize it to a string */
}
以下是使用Dexie.js作為IndexedDB-wrapper的特定解決方案的完整代碼 。 隨意使用它!
如果您正在討論表單數據,那么您可以截取fetch事件並以與下面類似的方式讀取表單數據,然后將數據保存在indexedDB中。
//service-worker.js
self.addEventListener('fetch', function(event) {
if(event.request.method === "POST"){
var newObj = {};
event.request.formData().then(formData => {
for(var pair of formData.entries()) {
var key = pair[0];
var value = pair[1];
newObj[key] = value;
}
}).then( ...save object in indexedDB... )
}
})
通過使用Cloud Firestore脫機持久性,可以獲得另一種提供完整脫機體驗的方法。
POST / PUT請求在本地緩存數據庫上執行,然后在用戶恢復其Internet連接時自動同步到服務器(請注意,有500個脫機請求的限制)。
遵循此解決方案需要考慮的另一個方面是,如果多個用戶具有同時進行同步的脫機更改,則無法保證更改將按照服務器上的正確時間順序執行,因為Firestore使用先到先服務邏輯。
根據https://w3c.github.io/ServiceWorker/#cache-put (第4點)。
if(request.method !== "GET") {
return Promise.reject('no-match')
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.