如何更改响应的标头?

mjs*_*mjs 6 javascript service-worker

是否可以更改Response对象的标题,如返回的fetch()?

假设我想通过resFn以下方式转换响应:

self.addEventListener('fetch', function (event) {
  event.respondWith(fetch(event.request).then(resFn));
});
Run Code Online (Sandbox Code Playgroud)

应该是什么resFn()样子?一种尝试:

function resFn(res) {
  res = res.clone();
  res.headers.set("foo", "bar");
  return res;
}
Run Code Online (Sandbox Code Playgroud)

失败TypeError: Failed to execute 'set' on 'Headers': Headers are immutable

(一个单独的问题和答案解释了如何更改请求的标头。鉴于 theRequestResponse对象惊人地不同(不同的属性,它们的构造函数采用不同的参数),是否适用相同的解决方案?)

mjs*_*mjs 8

这可以通过“手动”克隆响应来完成:

function resFn(res) {
  return newResponse(res, function (headers) {
    headers.set("foo", "bar");
    return headers;
  });
}
Run Code Online (Sandbox Code Playgroud)

newResponse()辅助函数在哪里:

function newResponse(res, headerFn) {

  function cloneHeaders() {
    var headers = new Headers();
    for (var kv of res.headers.entries()) {
      headers.append(kv[0], kv[1]);
    }
    return headers;
  }

  var headers = headerFn ? headerFn(cloneHeaders()) : res.headers;

  return new Promise(function (resolve) {
    return res.blob().then(function (blob) {
      resolve(new Response(blob, {
        status: res.status,
        statusText: res.statusText,
        headers: headers
      }));
    });
  });

}
Run Code Online (Sandbox Code Playgroud)

请注意,newResponse()返回一个Promise<Response>.

  • 天哪,这非常复杂,我认为只需要做一些类似 *res.headers.set("HeaderName", "HeaderValue")* 的事情,结果标头是不可变的 (2认同)

Mat*_*Way 6

当前的答案非常冗长。您可以通过执行以下操作来实现相同的目的:

const newHeaders = new Headers(initialResponse.headers)
newHeaders.set('foo', 'bar')
const newResponse = new Response(initialResponse.body, {
  headers: newHeaders
})  
Run Code Online (Sandbox Code Playgroud)

这个问题的最初尝试很接近。当您创建 headers 对象时,它不是不可变的,只有在响应对象上设置时它才变得不可变。