Установите заголовок по умолчанию для каждого запроса fetch()

Возможно ли, используя fetch API, чтобы установить заголовки по умолчанию для каждого отдельного запроса?
То, что я хочу сделать, это установить заголовок Authorization всякий раз, когда в localStorage есть токен json web. Мое текущее решение - установить заголовки с помощью этой функции:

export default function setHeaders(headers) {
    if(localStorage.jwt) {
        return {
            ...headers,
            'Authorization': `Bearer ${localStorage.jwt}`
        }
    } else {
        return headers;
    }
}

Настройка заголовков в запросе выборки будет выглядеть следующим образом:

return fetch('/someurl', {
        method: 'post',
        body: JSON.stringify(data),
        headers: setHeaders({
            'Content-Type': 'application/json'
        })
    })

Но должен быть лучший способ сделать это. В настоящее время я разрабатываю приложение React/Redux/Express, если это поможет.

Ответ 1

Вы можете использовать Axios вместо fetch, с Interceptors

const setAuthorization = (token) => {

  api.interceptors.request.use((config) => {
    config.headers.Authorization = 'Bearer ' + token;
    return config;
  });

}

Где Api - объект axios с базовым URL

const api= axios.create({
  baseURL: 'http://exemple.com'
});

И когда вы получаете свой токен, вам просто нужно вызвать функцию setAuthorization.

Источник: Axios README.md

Ответ 3

Создание обертки fetch может решить вашу проблему:

function updateOptions(options) {
  const update = { ...options };
  if (localStorage.jwt) {
    update.headers = {
      ...update.headers,
      Authorization: 'Bearer ${localStorage.jwt}',
    };
  }
  return update;
}

export default function fetcher(url, options) {
  return fetch(url, updateOptions(options));
}

Вы также получаете дополнительное преимущество, заключающееся в возможности легко переключать клиента запросов на все вызовы в вашем приложении, если вы решите, что вам больше нравится Axios или другой пакет. И вы можете делать другие вещи, например, проверять, является ли options.body объектом, и добавлять заголовок 'Content-Type: application/json.