簡體   English   中英

使用Service Worker 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM