Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to alter the headers of a Response?

Is it possible to alter the headers of a Response object, as returned by fetch()?

Suppose I want to transform a response via resFn:

self.addEventListener('fetch', function (event) {
  event.respondWith(fetch(event.request).then(resFn));
});

What should resFn() look like? One attempt:

function resFn(res) {
  res = res.clone();
  res.headers.set("foo", "bar");
  return res;
}

Fails with TypeError: Failed to execute 'set' on 'Headers': Headers are immutable.

(A separate question and answer explain how to alter the headers of a request. Given that the the Request and Response objects are surprisingly dissimilar (different properties, and their constructors take different arguments), does the same solution apply?)

like image 740
mjs Avatar asked Feb 15 '16 23:02

mjs


People also ask

How do you set a response header in Java?

Setting Response Headers from Servlets The most general way to specify headers is to use the setHeader method of HttpServletResponse. This method takes two strings: the header name and the header value. As with setting status codes, you must specify headers before returning the actual document.

How do I add a header to API response?

Adding Custom Header for Individual Response We create a very basic HTTP GET endpoint. Within this endpoint, we access the Response object through the HttpContext object. Then, we add a new header, with the name of x-my-custom-header and a value of individual response .


2 Answers

This can be done by "manually" cloning the response:

function resFn(res) {
  return newResponse(res, function (headers) {
    headers.set("foo", "bar");
    return headers;
  });
}

where the newResponse() helper function is:

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

}

Note that newResponse() returns a Promise<Response>.

like image 79
mjs Avatar answered Oct 15 '22 08:10

mjs


The current answer is quite verbose. You can achieve the same thing by doing the following:

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

The initial attempt in the question was close. When you create a headers object it isn't immutable, it only becomes immutable when set on the response object.

like image 24
Matt Way Avatar answered Oct 15 '22 08:10

Matt Way