2016-02-15 23 views
6

Czy można zmienić nagłówki obiektu Request, który jest odbierany przez zdarzenie fetch?Jak zmienić nagłówki żądania?

dwóch próbach:

  1. modyfikować istniejące nagłówki:

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

    nie powiedzie się z Failed to execute 'set' on 'Headers': Headers are immutable.

  2. Utwórz nowe Request obiektu:

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

    nie powiedzie się z Failed to construct 'Request': Cannot construct a Request with a Request whose mode is 'navigate' and a non-empty RequestInit.

(Patrz również How to alter the headers of a Response?)

Odpowiedz

8

Tworzenie nowego obiektu żądania działa tak długo, jak ustawić wszystkie opcje:

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

nie można używać oryginalnego mode jeśli jest navigate (to dlaczego były coraz wyjątek) i prawdopodobnie chcesz przekazać przekierowanie z powrotem do przeglądarki, aby umożliwić zmianę adresu URL, zamiast pozwolić mu na obsługę przez fetch.

Upewnij się, że nie ustawiłeś treści w żądaniach GET - pobieranie nie podoba się, ale przeglądarki czasami generują żądania GET z treścią w odpowiedzi na przekierowania z żądań POST. fetch to nie podoba.

+0

Czy zdajesz sobie sprawę, dlaczego "tryb" nawigacji "byłby problemem? – mjs

+3

Krok 12.1 https://fetch.spec.whatwg.org/#dom-request: "Jeśli tryb żądania jest" nawiguj ", wyrzuć TypeError.". – Marco

2

Czy próbowałeś roztworem podobny do tego w pytanie, o którym wspomniałeś (How to alter the headers of a Response?)?

W książce serwisowej dla robotników ręcznie kopiujemy obiekty zamówienia, aby je przechowywać w IndexedDB (https://serviceworke.rs/request-deferrer_service-worker_doc.html). To z innego powodu (chcieliśmy przechowywać je w pamięci podręcznej, ale nie możemy przechowywać żądań POST z powodu https://github.com/slightlyoff/ServiceWorker/issues/693), ale powinno to również dotyczyć tego, co chcesz zrobić.

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