Как изменить заголовки ответа?
Можно ли изменить заголовки Response
объект, возвращаемый fetch()
?
Предположим, я хочу преобразовать ответ через resFn
:
self.addEventListener('fetch', function (event) {
event.respondWith(fetch(event.request).then(resFn));
});
Что должно resFn()
выглядит как? Одна попытка:
function resFn(res) {
res = res.clone();
res.headers.set("foo", "bar");
return res;
}
Сбой с TypeError: Failed to execute 'set' on 'Headers': Headers are immutable
,
(Отдельный вопрос и ответ объясняют, как изменить заголовки запроса. Учитывая, что Request
а также Response
объекты удивительно различны (разные свойства и их конструкторы принимают разные аргументы), применяется ли одно и то же решение?)
2 ответа
Это можно сделать путем "ручного" клонирования ответа:
function resFn(res) {
return newResponse(res, function (headers) {
headers.set("foo", "bar");
return headers;
});
}
где 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
}));
});
});
}
Обратите внимание, что newResponse()
возвращает Promise<Response>
,
Текущий ответ довольно подробный. Вы можете добиться того же, выполнив следующие действия:
const newHeaders = new Headers(initialResponse.headers)
newHeaders.set('foo', 'bar')
const newResponse = new Response(initialResponse.body, {
headers: newHeaders
})
Первая попытка в вопросе была близка. Когда вы создаете объект заголовков, он не является неизменяемым, он становится неизменным только тогда, когда установлен в объекте ответа.