Рубрики
Без рубрики

Обработка CORS в экспресс

Как разрешить межсайтовые запросы, настроив CORS

Приложение JavaScript, запущенное в браузере, обычно может получать доступ к ресурсам HTTP только из того же домена (источника), который их обслуживает.

Загрузка изображений или сценариев/стилей из одного источника всегда работает. Кроме того, при загрузке веб-шрифтов с помощью @font-face по умолчанию установлена политика “того же происхождения”. Аналогично с другими, менее популярными вещами (такими как текстуры WebGL и drawImage ресурсы, загруженные в API Canvas).

Однако вызовы XHR и Fetch на внешний сторонний сервер завершатся ошибкой. Это если только сторонний сервер не реализует механизм, позволяющий устанавливать соединение и запрашивать ресурсы для загрузки и использования.

Этот механизм называется CORS , Совместное использование ресурсов из разных источников .

Одна очень важная вещь, которая нуждается в CORS, – это модули ES, недавно представленные в современных браузерах.

Если вы не настроите политику CORS на сервере , которая позволяет ему обслуживать сторонние источники, запрос не будет выполнен.

Пример выборки:

Пример XHR:

Ресурс из разных источников не работает, если он:

  • в другой домен
  • в другой поддомен
  • на другой порт
  • к другому протоколу

ЯДРА предназначены для вашей безопасности, чтобы предотвратить использование злоумышленниками любой веб-платформы, которую вы используете.

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

Как?

Это зависит от вашего стека на стороне сервера.

Поддержка браузера

Довольно хорошо (в основном все, кроме IE<10):

Пример с Экспресс

Если вы используете Node.js и выразите в качестве основы, используйте пакет промежуточного программного обеспечения CORS .

Вот простая реализация экспресс- Node.js сервер:

const express = require('express')
const app = express()

app.get('/without-cors', (req, res, next) => {
  res.json({ msg: '😞 no CORS, no party!' })
})

const server = app.listen(3000, () => {
  console.log('Listening on port %s', server.address().port)
})

Если вы нажмете /без ядер с запросом на выборку из другого источника, это вызовет проблему CORS.

Все, что вам нужно сделать, чтобы все работало гладко, – это запросить пакет cors , связанный выше, и передать его в качестве функции промежуточного программного обеспечения обработчику запросов конечной точки:

const express = require('express')
const cors = require('cors')
const app = express()

app.get('/with-cors', cors(), (req, res, next) => {
  res.json({ msg: 'WHOAH with CORS it works! 🔝 🎉' })
})

/* the rest of the app */

Я сделал простой пример сбоя, вот его код: https://glitch.com/edit/#!/флавио-корс-клиент .

Это и есть Node.js Экспресс-сервер: https://glitch.com/edit/#!/флавиокопы-cors-пример-экспресс

Обратите внимание, что запрос, который завершается ошибкой из-за того, что сервер неправильно обрабатывает заголовки CORS, все еще принимается. Как вы можете видеть на панели “Сеть”, где вы можете увидеть сообщение, отправленное сервером:

Разрешать только определенные источники

Однако в этом примере есть проблема: ЛЮБОЙ запрос будет принят сервером как исходящий из другого источника.

Как вы можете видеть на панели “Сеть”, переданный запрос имеет заголовок ответа access-control-allow-origin: * :

Вам необходимо настроить сервер так, чтобы разрешать обслуживание только одного источника и блокировать все остальные.

Используя тот же cors Библиотека узлов, вот как бы вы это сделали:

const cors = require('cors')

const corsOptions = {
  origin: 'https://yourdomain.com',
}

app.get('/products/:id', cors(corsOptions), (req, res, next) => {
  //...
})

Вы также можете подавать больше:

const whitelist = ['http://example1.com', 'http://example2.com']
const corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  },
}

Предполетная подготовка

Есть некоторые запросы, которые обрабатываются “простым” способом. Все Запросы GET принадлежат к этой группе.

Также некоторые пост и ГОЛОВА запросы делают то же самое.

Запросы POST также входят в эту группу, если они удовлетворяют требованию использования типа контента

  • приложение/x-www-форма-urlencoded
  • составная часть/форма-данные
  • текст/обычный

Все остальные запросы должны проходить этап предварительного утверждения, называемый предполетным. Браузер делает это, чтобы определить, есть ли у него разрешение на выполнение действия, отправив запрос ПАРАМЕТРЫ .

Предполетный запрос содержит несколько заголовков, которые сервер будет использовать для проверки разрешений (не относящиеся к делу поля опущены):

OPTIONS /the/resource/you/request
Access-Control-Request-Method: POST
Access-Control-Request-Headers: origin, x-requested-with, accept
Origin: https://your-origin.com

Сервер ответит примерно так (не относящиеся к делу поля опущены):

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://your-origin.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE

Мы проверили наличие POST, но сервер сообщает нам, что мы также можем выдавать другие типы HTTP-запросов для этого конкретного ресурса.

Следуя Node.js В приведенном выше примере сервер также должен обработать запрос ПАРАМЕТРОВ:

var express = require('express')
var cors = require('cors')
var app = express()

//allow OPTIONS on just one resource
app.options('/the/resource/you/request', cors())

//allow OPTIONS on all resources
app.options('*', cors())

Оригинал: “https://flaviocopes.com/express-cors/”