Проектирование междоменного промежуточного ПО на основе nodejs koa2

koa

1. Есть много способов решить проблему кроссдоменности браузера

  1. Установите заголовки ответов, связанные с http Access-Control-*, через серверную часть
  2. через Jsonp
  3. Обратный прокси через nginx

Введение в эти три междоменных метода см. в другой моей статье:Как решить внешние междоменные проблемы

В этой статье в основном рассказывается о реализации первого междоменного решения на основе nodejs koa2 и разработке его как промежуточного программного обеспечения koa2.

2. Функции, реализуемые междоменным промежуточным ПО

  1. Поддержка междоменных файлов cookie
  2. Поддерживает указанные заголовки междоменных HTTP-запросов, такие как accesstoken и т. д.
  3. Кэшировать результаты предварительной проверки, а время кэширования установлено на 1 день (т.е. 86400 секунд).
  4. Когда метод http имеет значение OPTIONS, это предварительная проверка, и непосредственно возвращается пустое тело ответа, а соответствующий код состояния http — 204.

3. Код промежуточного ПО koa-cors

koa-cors.js

const URL = require('url');
/**
 * 关键点:
 * 1、如果需要支持 cookies,
 *    Access-Control-Allow-Origin 不能设置为 *,
 *    并且 Access-Control-Allow-Credentials 需要设置为 true
 *    (注意前端请求需要设置 withCredentials = true)
 * 2、当 method = OPTIONS 时, 属于预检(复杂请求), 当为预检时, 可以直接返回空响应体, 对应的 http 状态码为 204
 * 3、通过 Access-Control-Max-Age 可以设置预检结果的缓存, 单位(秒)
 * 4、通过 Access-Control-Allow-Headers 设置需要支持的跨域请求头
 * 5、通过 Access-Control-Allow-Methods 设置需要支持的跨域请求方法
 */
module.exports = async function (ctx, next) {
  const origin = URL.parse(ctx.get('origin') || ctx.get('referer') || '');
  if (origin.protocol && origin.host) {
    ctx.set('Access-Control-Allow-Origin', `${origin.protocol}//${origin.host}`);
    ctx.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE, PUT');
    ctx.set('Access-Control-Allow-Headers', 'X-Requested-With, User-Agent, Referer, Content-Type, Cache-Control,accesstoken');
    ctx.set('Access-Control-Max-Age', '86400');
    ctx.set('Access-Control-Allow-Credentials', 'true');
  }
  if (ctx.method !== 'OPTIONS') {
    // 如果请求类型为非预检请求,则进入下一个中间件(包括路由中间件等)
    await next();
  } else {
    // 当为预检时,直接返回204,代表空响应体
    ctx.body = '';
    ctx.status = 204;
  }
};

Доступ-Контроль-Разрешить-Происхождение:

Access-Control-Allow-Origin может быть установлен на*Подстановочные знаки, вы также можете указать конкретные адреса, такие как:https://developer.mozilla.org.

При установке Access-Control-Allow-Origin на*, это означает, что доступ ко всем ресурсам разрешен, но запросы с учетными данными в настоящее время не поддерживаются.

Поэтому, чтобы разрешить все запросы на доступ к ресурсам и поддержку с учетными данными, установите для него значение${origin.protocol}//${origin.host}(то есть динамически получать адрес посетителя)

Access-Control-Allow-Headers

Accept, Accept-Language, Content-Language, Content-Type поддерживаются по умолчанию (поддерживаются только application/x-www-form-urlencoded, multipart/form-data или text/plain).

Если в заголовок запроса необходимо добавить собственный http-заголовок, такой как access_token , вам необходимо добавить access_token в массив.

Access-Control-Allow-Credentials

Простое понимание заключается в поддержке файлов cookie

Access-Control-Max-Age

Установите время кеша возвращаемого результата запроса OPTIONS (предпечатного запроса) в с.

Относительно запросов OPTIONS: В случае непростых запросов и перекрестного происхождения браузер инициирует предварительный запрос параметров. Вы можете обратиться к другой моей статье:О предварительных запросах браузера

4. Как использовать

app.js

const cors = require('./middlewares/koa-cors');
app.use(cors); // 跨域

5. код на гитхабе

GitHub.com/simplecodec…

Справочная документация:

Access-Control-Allow-Headers

credentials

Access-Control-Allow-Credentials

Access-Control-Max-Age