Почему CORS различает «простые запросы» и «предварительные запросы»?

JavaScript

Примечание редактора: автор этой статьи: Хэ Шиджун (имя в сети Hax), старший архитектор интерфейса 360, более десяти лет активно участвует в сообществах разработчиков интерфейса и JavaScript. Незначительный вклад в несколько веб-стандартов, незначительный вклад в язык Groovy и косвенно в язык Swift, а также участие в обсуждениях многих новых проектов ECMAScript в последние годы. Он спроектировал и реализовал язык джедаев и использовал его в производственной среде, а также имеет небольшой практический опыт работы с самостоятельными языками программирования. Он был трехкратным продюсером QCon и получил награду «Отличный продюсер», а также часто выступает с лекциями, гостем и ведущим на многих других технических мероприятиях.

CORS (совместное использование ресурсов между источниками), совместное использование ресурсов между источниками (широко известное как «междоменный запрос»), каждый должен иметь базовое понимание. Если вы еще этого не знаете, вы можете прочитатьВведение в MDN, я не буду вдаваться в подробности здесь.

Однако при изучении CORS у некоторых друзей возникнут сомнения: почему CORS делит запросы на две категории: простые запросы и предварительные запросы?

Если мы посмотрим на различие между простыми запросами и предварительными запросами, мы увидим, что есть много условий:

  • Метод HTTP для простых запросов может быть только GET, HEAD или POST.
  • Заголовок HTTP простого запроса может быть только Accept/Accept-Language/Conent-Language/Content-Type и т. д.
  • Заголовок Content-Type для простых запросов может быть только text/plain, multipart/form-data или application/x-www-form-urlencoded.

Это выглядит очень сложно.

Так как же понимать эти ограничения?

По сути, простой запрос — это запрос, который может отправить обычная HTML-форма, не полагаясь на скрипты.Например, если метод формы указан как POST, атрибут enctype можно использовать для указания того, как кодировать содержимое формы. Форма Правовые значения выше трех видов.

Непростые запросы — это запросы, которые нельзя реализовать с помощью обычных HTML-форм. Например, метод PUT, потребность в других методах кодирования контента, настраиваемые заголовки и т. д.

Что касается серверов, во-первых, многие серверы вообще не предназначены для использования в разных источниках. Конечно, если вы не предоставите заголовки ответа CORS, браузер не будет использовать ответ, но сам запрос может иметь последствия. Так что лучше по умолчанию отключить запросы между источниками.

Во-вторых, для ответа на вопрос, принимает ли запрос перекрестное происхождение, может быть задействована дополнительная вычислительная логика. Эта логика может быть очень простой, например всегда выпускать. Это также может быть более сложным, и результаты могут зависеть от того, какой ресурс и какие операции происходят из какого источника. Для браузера это так же просто, как разрешить ресурсу перекрестное происхождение; для сервера вычислительные затраты могут быть большими или малыми. Поэтому мы надеемся, что лучше не заставлять сервер выполнять вычисления для каждого запроса.

Таким механизмом является CORS-preflight.Браузер сначала делает отдельный запрос, спрашивая сервер, может ли ресурс быть перекрестным, и если нет, он не отправляет фактический запрос. Обратите внимание, что разрешение, а затем запрос означают, что запросы между источниками отключены по умолчанию. Если это разрешено, браузер запомнит, а затем отправит фактический запрос, а затем каждый раз будет запрашивать напрямую, не спрашивая сервер, может ли он выполнять перекрестное происхождение. Поэтому, если сервер хочет поддерживать кросс-начало, ему нужно только выполнить расчет лицензии на кросс-начало для предварительной проверки. Сам реальный код ответа вообще не заботится об этом. А поскольку предварительная проверка является разрешительной, это означает, что ничего не нужно делать, если сервер не собирается принимать кросс-происхождение.

Но этот механизм можно ограничить только непростыми запросами. При обработке простых запросов, если сервер не намерен принимать запросы из разных источников, он не может полагаться на механизм предварительной проверки CORS. Поскольку обычные формы также могут инициировать простые запросы без CORS, по умолчанию невозможно запретить перекрестное происхождение.

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

Некоторые люди интерпретируют простые запросы без предварительной проверки как «обратно совместимые». Это тоже не может быть ошибкой. Но строго говоря, не "для обратной совместимости" выпускать нельзя. Теоретически браузеры могут по-разному обрабатывать запросы формы и запросы без формы — предварительная проверка не отправляется для традиционных отправлений формы из разных источников, чтобы поддерживать совместимость, и только запросы без формы из разных источников отправляются в предварительную проверку.

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

И если вы это сделаете, сервер по умолчанию разрешит кросс-оригинальные формы.Если вы хотите контролировать кросс-оригинал, вам все равно придется выполнять логику кросс-оригинальных вычислений непосредственно в обработке ответов (как и раньше); с другой стороны, серверу необходимо увеличить поддержку ответов для предварительных запросов, выполняя аналогичную логику вычислений между источниками для управления одними и теми же запросами между источниками из неформ. У серверов обычно нет необходимости различать различия между формами и не формами, поэтому делать это просто означает бросать инженеров на стороне сервера.

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

О Еженедельнике Циу

«Qiwu Weekly» — это сообщество передовых технологий, управляемое профессиональной командой «Qiwu Troupe» компании 360. Подписавшись на официальный аккаунт, вы можете отправить нам статью, отправив ссылку прямо на фон.