Javascript Serviceworker:处理和重新发送请求主体

我想使用Javascript服务工作者记录外发请求。我当前的方法是这样的:

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);
});

This works fine for GET requests, but it doesn't work for the body of POST/PUT requests. I tried using body: event.request.body.blob(), but that did not work either.

是否有一种简单的方法可以访问服务工作者中的获取请求的主体并将其重新发送到其他地方?

评论
  • 樱小桃~
    樱小桃~ 回复

    可以根据发送的不同类型以不同方式获取请求正文。

    The following method are available to fetch body on event.request

    arrayBuffer()   blob()   json()   文本()   formData()

    You can make use of event.request.headers and check content-type before calling the required method to get the body

    Please check this blog post for more details

  • 淡夏之
    淡夏之 回复

    您可以执行以下操作:

    self.addEventListener('fetch', event => {
      const requestClone = event.request.clone()
    
      event.respondWith(
        (async function() {
          const params = await request.text().catch(err => err)
    
          if (params instanceof Error) {
            // this is a simple check, but handle error 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()

    假设以上代码段包含在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)