2016-02-15 12 views
6

Ist es möglich, die Header des Objekts Request zu ändern, das vom Ereignis fetch empfangen wird?Wie ändern Sie die Header einer Anfrage?

Zwei Versuche:

  1. Ändern bestehender Header:

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

    schlägt mit Failed to execute 'set' on 'Headers': Headers are immutable.

  2. Neues Request Objekt:

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

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

(Siehe auch How to alter the headers of a Response?)

Antwort

8

ein neues Request-Objekt erstellen funktioniert, solange Sie alle Optionen festgelegt:

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

Sie können nicht die ursprüngliche mode verwenden, wenn es navigate ist (das ist, warum Sie eine Ausnahme waren immer), und Sie Wahrscheinlich möchten Sie die Weiterleitung zurück an den Browser übergeben, damit sie ihre URL ändert, anstatt fetch damit umgehen zu lassen.

Stellen Sie sicher, dass Sie Körper nicht auf GET-Anforderungen festlegen - Fetch mag es nicht, aber Browser generieren manchmal GET-Anforderungen mit dem Textkörper, wenn sie auf Weiterleitungen von POST-Anfragen reagieren. fetch mag es nicht.

+0

Wissen Sie, warum ein 'Modus' von' Navigieren' ein Problem wäre? – mjs

+3

Schritt 12.1 von https://fetch.spec.whatwg.org/#dom-request: "Wenn der Modus der Anfrage" navigate "ist, werfen Sie einen TypeError.". – Marco

2

Haben Sie mit einer Lösung versucht, ähnlich dem in der Frage, die Sie erwähnen (How to alter the headers of a Response?)?

Im Service Worker Cookbook kopieren wir Request-Objekte manuell, um sie in IndexedDB zu speichern (https://serviceworke.rs/request-deferrer_service-worker_doc.html). Es ist aus einem anderen Grund (wir wollten sie in einem Cache speichern, aber wir können keine POST-Anfragen wegen https://github.com/slightlyoff/ServiceWorker/issues/693 speichern), aber es sollte auch für das, was Sie tun möchten, anwendbar sein.

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