【问题标题】:Javascript serviceworker: Processing & resending body of requestJavascript serviceworker:处理和重新发送请求正文
【发布时间】:2020-09-10 12:43:34
【问题描述】:

我想使用 Javascript serviceworker 来记录传出请求。我目前的做法是这样的:

self.addEventListener('fetch', function(event) {

    var req = new Request("https://example.com?url=" + encodeURI(event.request.url), {
        method: event.request.method,
        headers: event.request.headers,
        body: event.request.body
    });

    fetch(req);
});

这适用于 GET 请求,但不适用于 body 的 POST/PUT 请求。我尝试使用body: event.request.body.blob(),但也没有用。

有没有一种简单的方法可以在 serviceworkers 中访问获取的请求的主体并将其重新发送到其他地方?

【问题讨论】:

  • event.request.body 是一个ReadableStream,所以应该没问题传递给Request,就像你尝试过的那样。但是不要指望.blob()能起作用,ReadableStreams没有这样的方法……

标签: javascript service-worker fetch-api


【解决方案1】:

您可以执行以下操作:

self.addEventListener("fetch", (event) => {
  const requestClone = event.request.clone();

  event.respondWith(
    (async function () {
      const params = await requestClone.json().catch((err) => err);

      if (params instanceof Error) {
        // this is a simple check, but handle errors appropriately
      }

      if (event.request.method === "POST") {
        console.log(`POST request with params: ${params}`);
        // do work here
      }
      return fetch(event.request);
    })()
  );
});

请注意,您必须为 event.request 创建一个克隆,以便能够在其上调用 text 方法,因为请求是一个流并且只能使用一次,所以如果您遇到问题试图获取请求的参数,然后将其用于其他用途。

此外,您可以使用以下任何方法从请求中检索正文,因此请使用适当的方法:

  • event.request.arrayBuffer()
  • event.request.blob()
  • event.request.json()
  • event.request.text()
  • event.request.formData()

假设上述代码 sn-p 包含在您的 ServiceWorker 文件中,以下示例将为您提供所需的内容:

fetch("https://jsonplaceholder.typicode.com/posts", {
  method: "POST",
  body: JSON.stringify({ title: "foo", body: "bar", userId: 1 }),
  headers: { "Content-Type": `application/json` },
})
  .then((response) => response.json())
  .then((json) => console.log(`fetch response`, json))
  .catch((error) => console.error(`fetch error`, error));

// console logs
//  >> POST request with {"title":"foo","body":"bar","userId":1} (worker.js)
//  >> fetch response {title: "foo", body: "bar", userId: 1, id: 101} (index.js)

【讨论】:

  • 谢谢!我曾希望也可以通过这种方式访问​​通过<form> 标签执行的请求,但似乎并非如此。记录在浏览器中访问的 URL,以及通过fetch/XMLHttpRequest<img> 标签执行的请求,但不通过<form>
  • @tim forms 和 actions 的工作方式与 AJAX 请求略有不同 - 您可以使用 JavaScript 拦截该表单提交并使用 fetch 发出请求,以便你可以使用service workers
  • 让我吃惊的是,浏览器中的访问URL&img请求也可以被拦截,所以看起来并不是只是 AJAX请求。看来我想做的事情是行不通的,但我还是学到了一些东西,所以谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 2016-03-02
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多