当前位置: 首页 > 知识库问答 >
问题:

使用Service Worker获取侦听器请求修改

通博实
2023-03-14

我试图在来自应用程序的所有网络请求上添加一个自定义头,并试图通过服务工作者获取来实现这一点。标题的内容需要来自应用程序(客户端),所以在响应任何事件之前,我需要等待客户端的响应。下面是我实现这一目标的尝试

这是我的获取侦听器代码

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的新手,所以如果有一些愚蠢的错误,请原谅我。

从ServiceWorker调试控制台,我发现它在事件发生后立即进入catch块。respondWith()调用,所以可能有什么问题?

共有1个答案

孔扬
2023-03-14

您必须调用FetchEvent。在获取处理程序中同步响应()。在代码中,您正在同步调用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.

 类似资料:
  • 问题内容: 是否有原因导致代码中显示的动作侦听器内部?另外,如果有,我该如何解决此错误? 问题答案: 您可以使用一个不错的简单技巧… 如果未为按钮指定,则使用按钮的。 现在,如果您确实指定了按钮的属性,并且您仍然想知道文本(对我来说似乎很奇怪),则可以使用更多类似…

  • 在终端上,我得到了这个错误:$./asadmin start-domain domain1 找不到默认的域目录。此系统属性没有值:com.sun.aas.domainsroot命令启动-域失败。 在Eclipse上,我得到了这个运行时异常:在Felix平台上启动GlassFish 玻璃鱼4 拜托,你知道怎么解决这个问题吗?

  • 我正在实现一个片段,该片段调用两个。

  • **服务器** **客户** 并且我运行它,ip是环回(127.0.0.1),端口是7755。 客户端套接字的对等ip:127.0.0.1 客户端套接字的对等端口6311 -1 0 0 0 我的问题是,如果监听(服务器)套接字只处理客户端的连接,那么它的对等端不应该存在?那个错误的IP和端口是什么?只是垃圾值?

  • 我使用Antlr4和C#Target。在我的语法中有一个简单的lexer规则如下

  • 您好,我正试图通过刷新令牌并重试请求,找出如何实现新的角度拦截器和处理错误。这是我一直遵循的指南:https://ryanchenkie.com/angular-authentication-using-the-http-client-and-http-interceptors 我成功缓存失败的请求,并可以刷新令牌,但我不知道如何重新发送以前失败的请求。我还想让它与我目前使用的解析器一起工作。 t