How to change request headers?

Is it possible to change the headers of the Request object received by the fetch event?

Two attempts:

  1. Modify existing headers:

     self.addEventListener('fetch', function (event) { event.request.headers.set("foo", "bar"); event.respondWith(fetch(event.request)); }); 

    Failed to execute 'set' on 'Headers': Headers are immutable Failed to execute 'set' on 'Headers': Headers are immutable .

  2. Create a new Request object:

     self.addEventListener('fetch', function (event) { var req = new Request(event.request, { headers: { "foo": "bar" } }); event.respondWith(fetch(req)); }); 

    Failed to construct 'Request': Cannot construct a Request with a Request whose mode is 'navigate' and a non-empty RequestInit.

(See Also How to change response headers? )

+11
javascript service-worker
source share
3 answers

Creating a new query object works until you set all the parameters:

 // request is event.request sent by browser here var req = new Request(request.url, { method: request.method, headers: request.headers, mode: 'same-origin', // need to set this properly credentials: request.credentials, redirect: 'manual' // let browser handle redirects }); 

You cannot use the original mode if it is navigate (why did you get the exception), and you probably want to pass the redirect back to the browser to change its URL instead of letting fetch handle it.

Make sure that you do not set the body in GET requests - you don’t like the selection, but browsers sometimes generate GET requests with the body when responding to redirects from POST requests. fetch doesn't like it.

+11
source share

Have you tried with a solution similar to the solution in the question you mentioned ( How to change the response headers? )?

In the Service Worker Cookbook, we manually copy Request objects to store them in IndexedDB ( https://serviceworke.rs/request-deferrer_service-worker_doc.html ). This is for a different reason (we wanted to store them in the cache, but we cannot store POST requests because of https://github.com/slightlyoff/ServiceWorker/issues/693 ), but it should be applicable to ensure that you want to do.

 // Serialize is a little bit convolved due to headers is not a simple object. function serialize(request) { var headers = {}; // `for(... of ...)` is ES6 notation but current browsers supporting SW, support this // notation as well and this is the only way of retrieving all the headers. for (var entry of request.headers.entries()) { headers[entry[0]] = entry[1]; } var serialized = { url: request.url, headers: headers, method: request.method, mode: request.mode, credentials: request.credentials, cache: request.cache, redirect: request.redirect, referrer: request.referrer }; // Only if method is not `GET` or `HEAD` is the request allowed to have body. if (request.method !== 'GET' && request.method !== 'HEAD') { return request.clone().text().then(function(body) { serialized.body = body; return Promise.resolve(serialized); }); } return Promise.resolve(serialized); } // Compared, deserialize is pretty simple. function deserialize(data) { return Promise.resolve(new Request(data.url, data)); } 
+5
source share

You can create a new query based on the original and override the headers:

 new Request(originalRequest, { headers: { ...originalRequest.headers, foo: 'bar' } }) 
0
source share

All Articles