Как изменить заголовки ответа?

Можно ли изменить заголовки 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
})  

Первая попытка в вопросе была близка. Когда вы создаете объект заголовков, он не является неизменяемым, он становится неизменным только тогда, когда установлен в объекте ответа.

Другие вопросы по тегам