[英]Request formData in Service Worker - TypeError: Failed to fetch
[英]Request modification with service worker fetch listener
我試圖在來自應用程序的所有網絡請求上添加自定義標頭,並且我試圖通過服務工作者獲取來執行此操作。 標頭的內容必須來自app(client),因此我需要在響應任何事件之前等待客戶端的響應。 以下是我為實現這一目標的嘗試
這是我的提取偵聽器代碼
function send_message_to_client(client, msg){
return new Promise(function(resolve, reject){
var msg_chan = new MessageChannel();
msg_chan.port1.onmessage = function(event){
if(event.data.error){
reject(event.data.error);
}else{
resolve(event.data);
}
};
client.postMessage("SW Says: '"+msg+"'", [msg_chan.port2]);
});
}
self.addEventListener('fetch', function (event) {
event.waitUntil(async function () {
const client = await clients.get(event.clientId);
send_message_to_client(client, "Pass Transaction Details")
.then(function (m) {
var req = new Request(event.request.url, {
method: event.request.method,
headers: event.request.headers,
mode: 'same-origin',
credentials: event.request.credentials,
redirect: 'manual'
});
var res_obj = JSON.parse(m);
req.headers.append('MY_CUSTOM_HEADER', res_obj.hdr_val);
return event.respondWith(fetch(req));
})
.catch(function (error) {
console.log("Error after event.respondWith call");
console.log(error);
});
}());
});
這是我如何注冊此工作程序及其消息偵聽器的方法
navigator.serviceWorker.register('/my-sw.js', {scope: '/'})
.then(function(reg) {
navigator.serviceWorker.onmessage = function (e) {
var msg_reply = {
"message" : "Replying to SW request",
};
msg_reply.hdr_val = sessionStorage.getItem('__data_val');
console.log("Replying with "+ JSON.stringify(msg_reply));
e.ports[0].postMessage(JSON.stringify(msg_reply));
};
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
但顯然,它拍攝了2個請求,其中1個是原始請求,另外1個是帶有改頭的。
知道我在做什么錯嗎? 我是JavaScript的新手,所以如果有一些愚蠢的錯誤,請原諒我。
從服務工作者調試控制台,我發現它在event.respondWith()調用之后立即進入catch塊,所以那里可能出了什么問題?
您必須在提取處理程序中同步調用FetchEvent.respondWith()
。 在你的代碼在呼喚waitUntil()
同步,但調用respondWith()
后。 通過從獲取處理程序返回之前不調用respondWith()
,您是在告訴瀏覽器繼續其正常的網絡路徑而不會被攔截。
我想你想要這樣的東西:
self.addEventListener('fetch', function (event) {
// call respondWith() here
event.respondWith(async function () {
const client = await clients.get(event.clientId);
send_message_to_client(client, "Pass Transaction Details")
.then(function (m) {
var req = new Request(event.request.url, {
method: event.request.method,
headers: event.request.headers,
mode: 'same-origin',
credentials: event.request.credentials,
redirect: 'manual'
});
var res_obj = JSON.parse(m);
req.headers.append('MY_CUSTOM_HEADER', res_obj.hdr_val);
// just return the response back to the respondWith() here
return fetch(req);
})
// You probably want to add a .catch() to return some reasonable fallback
// response.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.