Выше мы видим типичную архитектуру современных веб-приложений.
Бэкэнд запускается на совершенно другой машине, и его API доступен всему миру.

На другом компьютере у нас есть приложение SPA, обслуживаемое экспрессом, среда которого построена с использованием webpack / browserify.

Из-за этой архитектуры нам приходится делать запросы CORS к нашему собственному бэкэнду.

Если вы немного прочитаете о запросах CORS в Mozilla Developer Network, вы обнаружите, что предварительные вызовы OPTIONS отправляются для всех GET / POST, если они не классифицируются как простые запросы.

Критерии рассмотрения простого запроса:

›Если в запросе используются методы

›Разрешенные заголовки

›Если заголовок Content-Type имеет значение

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Само собой разумеется, что это жесткие ограничения, которые можно рассматривать как простой запрос. В современных веб-приложениях, где большинство из нас использует заголовки авторизации, большинство запросов (даже GET) НЕ будут считаться простыми, и, следовательно, предварительный вызов будет отправлен в домен из браузера.

Это серьезный удар, который играет большую роль в задержке. Сначала я пошел по пути возиться с заголовками, чтобы сократить количество непростых запросов, но вскоре понял, что это огромная трата времени и кода.

Правильнее всего было бы направить запросы на ваш сервер приложений (тот, который обслуживает ваше созданное приложение и активы), который пересылает их на бэкэнд. А поскольку переадресация вызовов осуществляется с сервера на сервер, а не от браузера к серверу, мы успешно избегаем ВСЕХ предполетных запросов CORS!

Я добился этого, выбрав достаточно приличную библиотеку с открытым исходным кодом для промежуточного программного обеспечения прокси: http-proxy-middleware.

Более смелые души могут пойти по пути создания собственной прокси-смеси.

Шаги по перенаправлению вызовов на серверную часть через сервер приложений:

›Установите http-proxy-middleware .

›Перейдите к своему server.js или файлу с аналогичным именем, который запускает экспресс-сервер и указывает ему использовать промежуточное ПО прокси.

import proxy from 'http-proxy-middleware';
...
let options = {
 target: baseApiUrl, //api.example.com 
 changeOrigin: true,
 logLevel: ‘debug’,
 onError: function onError(err, req, res) {
 console.log(‘Something went wrong with the proxy middleware.’, err)
 res.end();
 }
};
app.use(‘/api’, proxy(options)); //only forward calls with ‘/api’ route

Таким образом, вызов, который ранее был api.example.com/posts/post_id, станет app.example.com/api/posts/post_id, который затем будет перенаправлен на в любом случае внутренний маршрут.

›Создавайте заголовки для вызовов через прокси.

const proxyOptions = {
 headers: {
 Accept: ‘application/json’,
 ‘Content-Type’: ‘application/vnd.example.v1+json’,
 },
};

Это необходимо отправить как параметр в любую библиотеку, которую вы используете для вызовов GET / POST / PUT / DELETE.

Ниже приведен пример вызова GET с использованием библиотеки axios.

axios.get(url, proxyOptions).then(response => resolve(response)).catch(error => resolve(error.response)); 

›И, наконец, не забудьте сообщить своему разработчику модулей о новом промежуточном программном обеспечении прокси, которое вы используете (код ниже предназначен для производственной конфигурации webpack).

module.exports = {
  entry: {
    app: ['./src/index.js'],
    vendor: [ 'axios', 'http-proxy-middleware']
  }
...
};

И все! Наслаждайтесь избеганием этих неприятных вызовов OPTIONS, используя указанную выше опцию :)