В этой статье вы познакомитесь с черной технологией HTTP.

задняя часть HTTP

Это третья статья из серии HTTP.Эта статья является расширенной статьей по HTTP.

В предыдущих двух статьях мы говорили о внедрении HTTP и обзоре всех распространенных заголовков HTTP, а в этой статье поговорим о некоторых HTTP-заголовках.黑科技.

Согласование HTTP-контента

Что такое обсуждение контента

В HTTP,内容协商Это механизм для обслуживания различных представлений ресурса по одному и тому же URL-адресу. Механизм согласования содержимого означает, что клиент и сервер в ответ согласовывают содержимое ресурса, а затем предоставляют клиенту наиболее подходящий ресурс. При согласовании содержимого в качестве стандарта оценки будут использоваться язык, набор символов, метод кодирования и т. д. ресурса ответа.

Типы переговоров по контенту

Существует три основных типа согласования контента:

  • 服务器驱动协商(Server-driven Negotiation)

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

  • 客户端驱动协商(Agent-driven Negotiation)

В этом методе согласования клиент выполняет согласование содержимого.

  • 透明协商(Transparent Negotiation)

Это комбинация управления сервером и клиентом, и это метод согласования контента между сервером и клиентом.

Существует множество типов согласования контента, основными из которых являютсяAccept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Language.

Как правило, клиент использует заголовок Accept, чтобы сообщить серверу, какие данные он ожидает получить, а сервер использует заголовок Content, чтобы сообщить клиенту, какие данные были фактически отправлены.

Зачем вам нужны переговоры по контенту

Зачем нам нужны переговоры по контенту? Прежде чем ответить на этот вопрос, давайте посмотрим на разницу между TCP и HTTP.

В стеке протоколов TCP/IP передаваемые данные в основномheader+bodyформат. Однако, поскольку TCP и UDP являются протоколами транспортного уровня, им все равно, что представляют собой данные тела, пока данные отправляются другой стороне, задача выполнена.

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

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

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

Заголовок согласования содержания

Accept

HTTP-заголовок запроса на принятие информирует клиента о том, что он может принятьMIMEтип

Так что же такое MIME-типы? Прежде чем ответить на этот вопрос, вы должны сначала понять, что такое MIME.

MIME: MIME (многоцелевые расширения почты Интернета) — это интернет-стандарт для описания типа содержимого сообщений. Сообщения MIME могут содержать текст, изображения, аудио, видео и другие данные, относящиеся к конкретному приложению.

То есть тип MIME на самом деле представляет собой набор типов содержимого сообщения. Так что же такое MIME-типы?

文本文件: текст/html, текст/обычный, текст/css, приложение/xhtml+xml, приложение/xml

图片文件: изображение/jpeg, изображение/gif, изображение/png

视频文件: видео/mpeg, видео/quicktime

应用程序二进制文件: приложение/октет-поток, приложение/zip

Например, если браузер не поддерживает отображение изображений PNG, то Accept не указывает изображение/png, а указывает типы изображений, такие как изображение/gif и изображение/jpeg, которые могут быть обработаны.

Общий тип MIME также будет соответствоватьqИспользуется с этим свойством, что такое q? q представляет вес, давайте посмотрим на пример

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Что это означает? Если вы хотите показатьТип носителя повышает приоритет, затем используйтеq=Чтобы дополнительно представлять значение веса, когда вес не отображается, значение по умолчанию 1,0, я дам вам таблицу, и вы поймете

q MIME
1.0 text/html
1.0 application/xhtml+xml
0.9 application/xml
0.8 * / *

Другими словами, это порядок размещения, сначала с большими весами, затем с низкими весами,application/xml;q=0.9представляет собой неделимое целое.

Accept-Charset

Атрибут Accept-charset указывает кодировку символов, принимаемую сервером для обработки данных формы, атрибут Accept-charset позволяет указать диапазон наборов символов, которые сервер должен поддерживать для корректной интерпретации данных в форме.

Accept-Charset не имеет соответствующего заголовка, сервер поместит это значение вContent-Typeкитайское использованиеcharset=xxxПредставлять,

Например, браузер запрашивает набор символов GBK или UTF-8, а затем сервер возвращает кодировку UTF-8, которая выглядит следующим образом.

Accept-Charset: gbk, utf-8
Content-Type: text/html; charset=utf-8

Accept-Language

Поле заголовка Accept-Language используется для информирования сервера о наборе естественного языка, который может обрабатывать пользовательский агент (имеется в виду китайский или английский язык и т. д.), и об относительном приоритете набора естественного языка. Можно указать сразу несколько наборов естественных языков. Как и поле заголовка Accept, по значению весаq=для указания относительного приоритета.

Accept-Language: en-US,en;q=0.5

Accept-Encoding

Указывает, что заголовок HTTP будет указывать кодировку содержимого, которую клиент ожидает от сервера, что обычно является алгоритмом сжатия. Accept-Encoding также принадлежит内容协商часть, используемая и выбранная клиентомContent-Encodingконтент возвращается.

Даже если и клиент, и сервер могут поддерживать один и тот же алгоритм сжатия, сервер может отказаться от сжатия и возврата, что может быть связано с этими двумя условиями:

  • Отправляемые данные уже были сжаты один раз, и второе сжатие не приведет к отправке данных меньшего размера.
  • Сервер перегружен и не может позволить себе снижение производительности при сжатии, обычно если сервер использует более 80% ЦП,Microsoftто рекомендуется не использовать сжатие

Вот как используется Accept-Encoding

Accept-Encoding: gzip
Accept-Encoding: compress
Accept-Encoding: deflate
Accept-Encoding: br
Accept-Encoding: identity
Accept-Encoding: *
Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5

В приведенных выше выражениях уже перечислены все свойства Accept-Encoding.

  • gzip: формат кодирования, сгенерированный программой сжатия файлов gzip с использованиемLempel-Ziv编码(LZ77)и 32-битный формат сжатия CRC, заинтересованные студенты могут прочитать (Хорошо. Wikipedia.org/wiki/LZ77_ahhh…

  • compress: использоватьLempel-Ziv-Welch(LZW)Сжатый формат алгоритма, заинтересованные студенты могут прочитать (Эн. Wikipedia.org/wiki/LZ W)

  • deflate: Формат сжатия с использованием структуры zlib и алгоритма сжатия deflate, см. (En. Wikipedia.org/wiki/Zlib)и (En. Wikipedia.org/wiki/D E flat…

  • br: Формат сжатия с использованием алгоритма Бротли, см. (Что ж, Wikipedia.org/wiki/br ОТ…

  • Формат кодирования по умолчанию, который не выполняет сжатие или изменения

  • *: соответствует любой кодировке содержимого, не указанной в заголовке, если она не указанаAccept-Encoding, это значение по умолчанию и не подразумевает поддержку

    Содержит любой алгоритм, просто не выражает предпочтения

  • ;q=Относительный приоритет представлен значением веса q, которое совпадает со значением поля заголовка Accept.

Content-Type

Заголовок сущности Content-Type используется для указания MIME-типа ресурса. В ответ заголовок Content-Type сообщает клиенту, каков на самом деле тип возвращаемого содержимого. Content-type имеет два значения: тип MIME и кодировку, например.

Content-Type: text/html; charset=UTF-8

В некоторых случаях браузеры будут выполнять прослушивание MIME и не обязательно будут учитывать значение этого заголовка; чтобы предотвратить такое поведение, заголовок X-Content-Type-Options может быть установлен на nosniff.

Content-Encoding

Заголовок объекта Content-Encoding используется для сжатия типов мультимедиа, он позволяет клиенту узнать, как выполнить операцию декодирования, чтобы клиент получил тип MIME, на который ссылается заголовок Content-Type. выражается следующим образом

Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
Content-Encoding: identity
Content-Encoding: br
Content-Encoding: gzip, identity
Content-Encoding: deflate, gzip

Content-Language

Заголовок объекта Content-Language используется для описания языка аудитории, чтобы пользователи могли различать их на основе предпочитаемого ими языка. Например

Content-Language: de-DE
Content-Language: en-US
Content-Language: de-DE, en-CA

Ниже, в соответствии с соответствующими заголовками запроса/ответа согласования контента, я перечислил изображение для вашей справки.Обратите внимание, что Accept-Charset не имеет соответствующего Content-Charset, но представлен Content-Type.

HTTP-аутентификация

HTTP предоставляет функции для управления доступом и аутентификации.Ниже приведено введение в HTTP-разрешения и функции аутентификации.

Общая структура HTTP-аутентификации

RFC 7235 определяет структуру HTTP-аутентификации, которую сервер может проверять по клиентским запросам, как определено в его документации. Клиенты также могут предоставлять аутентификационную информацию, как определено в их документации.

Рабочий процесс запроса/ответа выглядит следующим образом: сервер запускается с401(未授权)Статусный ответ клиенту сообщает клиенту, что серверу требуется информация для аутентификации, и клиент предоставляет по крайней мере одинwww-AuthenticateЗаголовок ответа для аутентификации авторизационной информации. Клиент, который хочет пройти аутентификацию через сервер, может добавить заголовок аутентификации в поле заголовка запроса для аутентификации личности.Общий процесс аутентификации выглядит следующим образом.

Сначала клиент инициирует HTTP-запрос без какого-либо заголовка аутентификации.Сервер отвечает на этот HTTP-запрос и обнаруживает, что информация HTTP не содержит учетных данных для аутентификации.www-AuthenticateЗаголовок возвращает 401, чтобы сообщить клиенту, что этот запрос не прошел проверку подлинности. Затем клиент выполняет аутентификацию пользователя и повторно инициирует HTTP-запрос после аутентификации.На этот раз HTTP-запрос содержит учетные данные аутентификации пользователя (обратите внимание, что весь процесс аутентификации должен быть защищен через соединение HTTPS).После достижения сервера сервер проверит информацию об аутентификации. Если он не соответствует информации об аутентификации сервера, он вернет403 ForbiddenУказывает, что аутентификация пользователя не удалась, если информация аутентификации удовлетворена, возврат200 OK.

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

Прокси-аутентификация

Поскольку аутентификация ресурса и аутентификация прокси-сервера могут сосуществовать, требуются разные заголовки и коды состояния, а в случае прокси-сервера возвращается код состояния.407(需要代理认证),Proxy-AuthenticateЗаголовок ответа содержит как минимум один случай, относящийся к прокси,Proxy-AuthorizationЗаголовок запроса используется для предоставления сертификата прокси-серверу. Давайте посмотрим на эти два заголовка по отдельности.

Proxy-Authenticate

HTTP Proxy-AuthenticateЗаголовок ответа определяет метод аутентификации, который следует использовать для доступа к ресурсам за прокси-сервером. Он аутентифицирует запрос к прокси-серверу, позволяя ему отправлять дальнейшие запросы. Например

Proxy-Authenticate: Basic
Proxy-Authenticate: Basic realm="Access to the internal site"

Proxy-Authorization

этот HTTP请求заголовок и вышеProxy-AuthenticateСращивание похоже, но концепция отличается, этот заголовок используется для предоставления учетных данных прокси-серверу, например.

Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

Ниже приведен процесс аутентификации запроса/ответа прокси-сервера.

Этот процесс аналогичен общему процессу, и мы не будем его подробно описывать.

Нет доступа

если代理服务器Полученных действительных учетных данных недостаточно для получения доступа к данному ресурсу, сервер должен использовать403 ForbiddenКод состояния для ответа. и401 Unauthorizedи407 Proxy Authorization Requiredотличается, пользователь не может быть аутентифицирован.

Заголовки WWW-Authenticate и Proxy-Authenticate

WWW-AuthenticateиProxy-AuthenticateЗаголовок ответа определяет метод аутентификации для получения доступа к ресурсу. Им необходимо указать, какую схему аутентификации использовать, чтобы клиенты, которые хотят авторизоваться, знали, как предоставлять учетные данные. Их общее представление следующее

WWW-Authenticate: <type> realm=<realm>
Proxy-Authenticate: <type> realm=<realm>

Думаю, вам будет любопытно посмотреть на это сверху<type>иrealmЧто это такое, давайте сейчас объясним.

  • <type>протокол аутентификации,Basicявляется наиболее часто используемым из следующих протоколов

определено в RFC 7617BasicСхема аутентификации HTTP, которая передает учетные данные в виде пары идентификатора пользователя и пароля, закодированной с использованием base64. (Заинтересованные учащиеся могут посмотретьtools.I ETF.org/HTML/RFC761…)

Другие протоколы аутентификации в основном

Протокол аутентификации Справочный источник
Basic чекRFC 7617, учетные данные в кодировке base64
Bearer чекRFC 6750, токены носителя для доступа к защищенным ресурсам OAuth 2.0
Digest чекRFC 7616, Firefox поддерживает только хэши md5, см. ошибкуbug 472823для поддержки шифрования SHA
HOBA чекRFC 7486
Mutual чекRFC 8120
AWS4-HMAC-SHA256 чекAWS docs
  • realmИспользуется для описания охраняемой территории или для обозначения степени защиты, это может быть что-то вродеДоступ к промежуточному сайтуили подобное, чтобы пользователь знал, какую область он хочет посетить.

Заголовки авторизации и прокси-авторизации

Заголовки запроса Authorization и Proxy-Authorization содержат учетные данные, используемые для аутентификации агента пользователя через прокси-сервер. Здесь снова требуется тип, за которым следуют учетные данные, которые могут быть закодированы или зашифрованы в зависимости от используемой схемы аутентификации. Обычно выражается следующим образом

Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

HTTP-кэш

поставив请求/响应Кэширование может помочь улучшить производительность системы,Web 缓存Задержка и сетевой трафик сокращаются, что сокращает время, необходимое ресурсу для получения блокировки. Из-за длинной ссылки и неконтролируемой сетевой задержки стоимость браузеров, использующих HTTP для получения ресурсов, относительно высока. Поэтому очень важно кэшировать данные и максимально повторно использовать их при следующем запросе. Когда веб-кеш имеет запрошенный ресурс в своем хранилище, он перехватывает запрос и возвращает ресурс напрямую, а не обращается к исходному серверу для повторной загрузки и извлечения. Это позволяет достичь двух небольших целей

  • Снизить нагрузку на сервер
  • Улучшить производительность системы

Давайте обсудим, что есть в кэшах HTTP.

различные виды кэша

Существует несколько различных типов кэширования HTTP, и их можно разделить на две основные категории:私有缓存и共享缓存.

  • Общий кеш. Общий кеш — это кеш, в котором хранятся запросы/ответы, повторно используемые несколькими пользователями.
  • Частный кэш: Частный кэш также известен как专用缓存, это работает только для одного пользователя.
  • Ресурсы с истекшим сроком действия не кэшируются: все запросы будут поступать напрямую на сервер, а сервер будет загружать ресурсы и возвращать их.

В основном мы обсуждаем浏览器缓存и代理缓存, но реальная ситуация заключается не только в этих двух видах кешей, но и в кешах шлюзов, CDN, обратных прокси-кешах и балансировщиках нагрузки, их развертывание на веб-серверах может повысить надежность, производительность и масштабируемость веб-сайтов и веб-приложений.

Не кэшировать просроченные ресурсы

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

no-cache принадлежит общему заголовку Cache-Control, и его общее представление выглядит следующим образом

Cache-Control: no-cache

также можно использоватьmax-age = 0для достижения эффекта не кеширования.

Cache-Control: max-age=0

приватный кеш

Частный кеш используется только для кэширования одного пользователя, вы могли видеть в настройках браузера.缓存, кэш браузера содержит все документы, загруженные сервером по HTTP. Этот кеш используется для включения операций перемотки вперед/назад и сохранения документов, к которым осуществляется доступ, без повторной отправки запроса на исходный сервер.

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

Cache-Control: private

общий кеш

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

Cache-Control: public

управление кешем

в HTTP/1.1Cache-ControlПоле общего заголовка используется для управления кешем, используя этот заголовок для определения политики кеша с помощью различных директив, которые он предоставляет. Ниже мы вводим эти свойства по очереди

не кэшировать

no-storeнастоящий不缓存, каждый раз, когда сервер получает запрос клиента, он возвращает последний ресурс клиенту.

Cache-Control: no-store

Кэшировано, но требует проверки

То же, что и выше. Не кэшировать ресурсы с истекшим сроком действия.

Частный и общий кэш

То же

кеш истек

Очень важная инструкция в кэшеmax-age, который является ресурсом, рассматриваемым как新鲜максимальное время, сExpiresВместо этого эта директива относится ко времени запроса. Активное кэширование часто можно добавить для файлов, которые не изменяются в приложении. Ниже представлено изображение mag-age

Cache-Control: max-age=31536000

проверка кеша

must-revalidateУказывает, что кеш должен проверять состояние устаревших ресурсов перед их использованием и что ресурсы с истекшим сроком использования не должны использоваться.

Cache-Control: must-revalidate

Ниже приведена схема проверки кеша.

какие свежие данные

Как только ресурс сохранен в кеше, теоретически он может использоваться кешем вечно. Однако, будь то кеш браузера или кеш прокси, его место для хранения ограничено, поэтому кеш будет периодически очищаться.Этот процесс называется缓存回收(cache eviction)(самостоятельный перевод). С другой стороны, кэш на сервере также регулярно обновляется.HTTP как протокол прикладного уровня является客户-服务器В этом режиме HTTP является протоколом без сохранения состояния, поэтому сервер не может уведомлять кэши и клиентов об изменении ресурсов. Так что сервер должен каким-то образом сообщить клиенту, что кеш обновился. Сервер будет предоставлять过期时间Концепция, которая информирует клиента о том, что до истечения этого срока ресурс新鲜的, то есть без изменений. Вне этого срока действия ресурс устарел.过期算法(Eviction algorithms)Новые ресурсы обычно используются вместо устаревших ресурсов.

Здесь следует отметить, что просроченные ресурсы не перерабатываются и не игнорируются.Когда кеш получает просроченные ресурсы, он будет использоватьIf-None-MatchПерешлите этот запрос, чтобы проверить, действителен ли он. Если он действителен, сервер вернет304 Not ModifiedЗаголовки ответа и без тела ответа, что экономит пропускную способность.

Ниже описана процедура использования общего кэширующего прокси.

Эту диаграмму должно быть легче понять, просто поговорим о роли Age, Age — это заголовок ответа HTTP, сообщающий клиенту, как давно исходный сервер создал ответ, и его единицей измерения является, заголовок Age обычно близок к 0, если он равен 0, он может быть получен с исходного сервера, если нет, то может быть создан прокси-сервером, то значение Age указывает на то, чтоЗначение времени с момента, когда кэшированный ответ снова инициирует проверку подлинности, до завершения проверки подлинности..

Действительность кеша определяется несколькими заголовками, а не одним заголовком. если указаноCache-control:max-age=N, то кеш будет храниться N секунд. Если этот общий заголовок не существует, он проверит его существование.ExpiresЗаголовок. Если заголовок Expires присутствует, его значение за вычетом значения заголовка Date определяет его достоверность. Наконец, еслиmax-ageиexpiresЕго не существует, просто поищитеLast-ModifiedЗаголовок, если он присутствует, срок действия кеша равен значению заголовка Date минус значение заголовка Last-modified, деленное на 10.

проверка кеша

Когда срок действия кэшированного ресурса будет достигнут, он будет снова проверен или извлечен. только если сервер предоставляет强验证器или弱验证器можно только проверить.

Когда пользователь нажимает кнопку перезагрузки, активируется повторная проверка. Если кэшированный ответ содержитCache-control:must-revalidateзаголовок, событие также запускается во время обычного просмотра. Другим фактором являются настройки проверки кеша на панели Advanced -> Cache Preferences. Существует возможность принудительной проверки каждый раз при загрузке документа.

Etag

Выше мы упомянули сильные и слабые валидаторы, заголовки, реализующие функциональность валидатора, официально являются ролью Etags, а это означает, что пользовательские агенты HTTP (например, браузеры) не знают, что представляет собой эта строка, и не могут предсказать ее значение. Если заголовок Etag является частью ответа ресурса, клиент может выдавать заголовок в будущих запросах.If-None-Match, чтобы проверить кэшированные ресурсы.

Last-ModifiedЗаголовок ответа можно использовать как слабый валидатор, поскольку у него есть только 1 секунда, чтобы определить разницу. если присутствует в ответеLast-Modifiedзаголовок, клиент может выдатьIf-Modified-SinceЗаголовки запросов для проверки кэшированных ресурсов. (Подробнее об Etag будет представлено в условном запросе)

избежать столкновения

Используя заголовки Etag и If-Match, вы можете обнаружить и избежать коллизий.

Например, при редактировании MDN текущий контент вики будет хеширован и помещен в Etag в ответе.

Etag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

При сохранении изменений на вики-странице (публикации данных) запрос POST будет включать заголовок If-Match со значением Etag для проверки достоверности.

If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Если хэши не совпадают, значит документ редактировался на середине, и возвращается412 Precondition FailedОшибка.

Кэш не занимает ресурсы

Другим типичным использованием заголовка Etag является кеширование неизмененных ресурсов. Если пользователь снова посещает данный URL-адрес (с установленным Etag), а URL-адрес устарел, клиент отправит его в поле заголовка If-None-Match. Значение Etag

If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Сервер сравнивает Etag клиента (отправленный через If-None-Match) с Etag, чтобы получить его текущую версию ресурса, и если оба значения совпадают (т.е. ресурс не изменился), сервер отправляет обратно304 Not ModifiedСостояние без тела, которое сообщает клиенту, что кеш ответа все еще доступен.

Междоменный HTTP CROS

Полное название КРОСCross-Origin Resource Sharing(CROS), в переводе на китайский跨域资源共享, это механизм. Что это за механизм? Это способ бегать в域(origin)Механизм, с помощью которого веб-приложениям на сервере предоставляется доступ к указанным ресурсам с разных исходных серверов. Прежде чем разобраться в этом механизме, необходимо понять, что域(origin)

Origin

веб-концепция域(Origin)содержаниеscheme(protocol) - 协议,host(domain) - 主机и URL для доступа к немуport - 端口определение. Два объекта имеют одинаковое происхождение, только если схема, хост и порт совпадают. Эта политика безопасности с тем же протоколом, тем же доменным именем и тем же портом также называется同源策略(Same Origin Policy). Некоторые операции ограничены контентом одного происхождения, который можно удалить с помощью CORS.

Междоменные функции

  • Ниже приведен пример междоменной проблемы. Посмотрите, понимаете ли вы, что такое междоменная проблема.
(1) http://example.com/app1/index.html
(2) http://example.com/app2/index.html

Имеют ли указанные выше два URL-адреса междоменные проблемы?

Приведенные выше два URL-адреса не имеют междоменных проблем, поскольку два URL-адреса имеют одинаковые协议(scheme)и主机(host)

  • Итак, есть ли у следующих двух междоменные проблемы?
http://Example.com:80
http://example.com

У этих двух URL также нет междоменных проблем, почему бы и нет, порты разные. По сути, два порта одинаковы.

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

Части протокола и доменного имени нечувствительны к регистру, но часть пути зависит от серверной платформы. Системы Windows и Mac OS X нечувствительны к регистру, в то время как серверные системы на базе UNIX и Linux чувствительны к регистру.

То есть вышеизложенноеExample.comиexample.comНа самом деле это URL-адрес, и, поскольку два адреса имеют одинаковую схему и хост, по умолчанию сервер доставляет HTTP-контент через порт 80, поэтому два вышеуказанных адреса также совпадают.

  • Имеются ли у следующих двух URL-адресов междоменные проблемы?
http://example.com/app1
https://example.com/app2

Схемы этих двух URL-адресов различаются, поэтому эти два URL-адреса имеют междоменные проблемы.

  • Давайте посмотрим, есть ли у следующих трех URL междоменные проблемы.
http://example.com
http://www.example.com
http://myapp.example.com

Эти три URL-адреса также имеют междоменные проблемы, поскольку они принадлежат разным хостам на одном сервере.

  • Имеют ли следующие два URL междоменные проблемы
http://example.com
http://example.com:8080

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

Та же политика происхождения

Из соображений безопасности браузеры ограничивают междоменные HTTP-запросы от скриптов.XMLHttpRequestи другиеFetch 接口последует同源策略(same-origin policy). То есть приложения, использующие эти API, которые хотят запрашивать одни и те же ресурсы, должны иметь одно и то же происхождение, если только ответы из других источников не включают также правильные заголовки CORS.

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

Выше мы упоминали, что два URL-адреса имеют одинаковое происхождение, если они имеют одинаковый протокол, хост и номер порта (если он указан). Вот несколько примеров, вы можете судить, имеют ли они тот же источник

целевой источникhttp://store.company.com/dir/page.html

URL Outcome Reason
store.company.com/enemy2/other. … тот же источник только путь разный
store.company.com/enemy/inner/ ах… тот же источник только путь разный
store.company.com/page.html разные источники Соглашение не работает
store.company.com:81/enemy/fear one.Контракт… разные источники Различные порты по умолчанию
news.company.com/enemy/fear one.contract… разные источники разные хосты

Теперь, когда я провел вас через два разных источника, теперь вы должны знать, как определить, принадлежат ли два URL-адреса одному и тому же источнику!

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

междоменный запрос

Запросы между источниками могут быть сделаны из следующих типов запросов:

  1. перечислитьXMLHttpRequestилиFetchAPI

Что такое XMLHttpRequest? (Я back-end программист, и я мало знаю о front-end. Позвольте мне кратко объяснить. Если объяснение не очень хорошее, пожалуйста, попросите начальство front-end не бить меня)

Все современные браузеры имеют встроеннуюXMLHttpReqeustОбъект, который можно использовать для запроса данных с сервера.

XMLHttpReqeust важен для разработчиков, объект XMLHttpReqeust можно использовать для следующих целей:

  • Обновление веб-страниц без повторного обновления страницы
  • Запросить данные с сервера после загрузки страницы
  • Получить данные с сервера после загрузки страницы
  • Отправка данных на сервер в фоновом режиме

Используя объект XMLHttpRequest(XHR) для взаимодействия с сервером, вы можете извлекать данные из URL-адреса, не обновляя всю страницу, что позволяет веб-странице обновлять части страницы, не прерывая пользователя. XMLHttpRequest вAJAXОн широко используется в асинхронном программировании.

Давайте поговорим о том, что такое Fetch API. Fetch предоставляет общее определение объектов запросов и ответов (и других сетевых запросов). Он также предоставляет определения связанных понятий, таких как семантика заголовков CORS и HTTP Origin, и заменяет их соответствующие определения в других местах.

  1. Веб-шрифты (для междоменного использования шрифтов в @font-face в CSS), чтобы сервер мог развертывать шрифты TrueType, которые могут использоваться только веб-сайтами, допускающими межсайтовую загрузку и использование.
  2. Текстуры WebGL
  3. использоватьdrawImage()Кадр изображения/видео, нарисованный на холсте
  4. CSS-формы для изображений

Обзор междоменных функций

Стандарт совместного использования ресурсов между источниками работает путем добавления новых заголовков HTTP, которые позволяют серверам описывать, каким источникам разрешено считывать информацию из веб-браузера. Кроме того, спецификация требует, чтобы браузеры имели методы HTTP-запроса (особенно методы GET или HTTP, отличные от методов POST с определенными типами MIME), которые могут вызывать побочные эффекты для данных сервера.预检запрос, используя метод запроса HTTP OPTIONS, чтобы запросить поддерживаемый метод с сервера, а затем批准После отправки фактического запроса. Сервер также может сообщить клиенту, следует ли его отправить вместе с запросом.凭据(например, файлы cookie и HTTP-аутентификация).

Примечание. Сбои CORS вызывают ошибку, но из соображений безопасности сведения об ошибке не относятся к JavaScript. Весь код знает, что произошла ошибка. Единственный способ определить, что не так, — посмотреть подробности в консоли браузера.

Контроль доступа

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

простой запрос

Некоторые запросы не срабатываютCORS预检(О предварительной проверке мы расскажем позже).简单请求запрос, который удовлетворяет всем следующим условиям

  • Допускаются следующие методы:GET,HEADиPOST

  • Помимо заголовков, которые автоматически устанавливаются пользовательскими агентами (например, Connection, User-Agent или другие заголовки, определенные в спецификации Fetch как запрещенные имена заголовков), единственные заголовки, которые разрешено устанавливать вручную, — это те, которые определены в спецификации Fetch. в видеCORS安全列出的请求标头,Они есть:

    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (описано ниже)
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  • Единственные допустимые значения для заголовка Content-Type:

    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  • В объектах XMLHttpRequestUpload, используемых в запросе, не зарегистрированы прослушиватели событий, доступ к которым можно получить с помощью свойства XMLHttpRequest.upload.

  • Объект ReadableStream не использовался в запросе.

    Например, предположим, что веб-контентhttps://foo.exampleхочу получитьhttps://bar.otherресурсы домена, то код на JavaScript может быть написан следующим образом.

    const xhr = new XMLHttpRequest();
    const url = 'https://bar.other/resources/public-data/';
       
    xhr.open('GET', url);
    xhr.onreadystatechange = someHandler;
    xhr.send(); 
    

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

Посмотрим, что в этом случае отправит браузер на сервер, и посмотрим, как ответит сервер:

GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example

Обратите внимание на заголовок запроса Origin , который указывает, что вызов поступил изhttps://foo.example. Посмотрим как ответит сервер

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[…XML Data…]

сервер отправитьAccess-Control-Allow-Originкак ответ. использоватьOriginзаголовок иAccess-Control-Allow-OriginПоказан простейший протокол управления доступом. В этом случае сервер используетAccess-Control-Allow-OriginВ ответ это означает, что доступ к ресурсу может получить любой домен.

если вhttps://bar.otherвладельцев ресурсов хотят ограничить доступ к ресурсу только сhttps://foo.exampleзапросы, они должны отправить ответ, например

Access-Control-Allow-Origin: https://foo.example

За исключением сейчасhttps://foo.exampleЛюбые домены, кромеhttps://bar.otherРесурсы.

предварительный запрос

В отличие от простых запросов, рассмотренных выше,预检Запрос проходит первымOPTIONSМетод отправляет HTTP-запрос к ресурсу в другом домене, чтобы определить, безопасно ли отправлять фактический запрос. межсайтовый вот такой预检, так как они могут повлиять на пользовательские данные.

Ниже приведен предварительный пример

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://bar.other/resources/post-here/');
xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
xhr.setRequestHeader('Content-Type', 'application/xml');
xhr.onreadystatechange = handler;
xhr.send('<person><name>Arun</name></person>'); 

В приведенном выше примере создается тело запроса XML для отправки с запросом POST. Дополнительно устанавливаются нестандартные заголовки запросовX-PINGOTHER, этот заголовок не является частью HTTP/1.1, но обычно полезен для веб-программ. по запросуContent-Typeиспользоватьapplication/xml, и установлен пользовательский заголовок, поэтому запрос预检. Как показано ниже

Как описано ниже, фактический POST-запрос не содержит заголовков Access-Control-Request-*, они необходимы только для запросов OPTIONS.

Давайте взглянем на полное взаимодействие клиент/сервер, начиная с предполетного запроса/ответа.

OPTIONS /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive

Строки 1-11 выше представляют предварительный запрос, который используется предварительным запросом.OPYIIONSметод, браузер определяет, нужно ли отправлять этот запрос, на основе параметров запроса, используемых приведенным выше фрагментом JavaScript, чтобы сервер мог ответить, может ли запрос быть отправлен с фактическими параметрами запроса. OPTIONS — это метод HTTP/1.1 для получения дополнительной информации с сервера, и это безопасный метод, то есть его нельзя использовать для изменения ресурсов. Обратите внимание, что вместе с запросом OPTIONS отправляются два других заголовка запроса (строки 9 и 10 соответственно).

Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

Access-Control-Request-MethodЗаголовок информирует сервер как часть предварительного запроса о том, что при отправке фактического запроса он будет использоваться.POSTМетод запроса отправляет запрос.

Access-Control-Request-HeadersЗаголовок информирует сервер о том, что при отправке запроса он будет отправлен вместе с пользовательскими заголовками X-PINGOTHER и Content-Type. Сервер может определить, принимать ли запрос в этом случае.

Строки 1–11 ниже — это ответы, отправленные сервером, указывающие наPOSTзапрос иX-PINGOTHERприемлемо, давайте сосредоточимся на следующих строках

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400

Сервер завершает ответ, указывая, что источникhttp://foo.exampleявляется приемлемым URL-адресом, который позволяетPOST、GET、OPTIONSСделать запрос, разрешить пользовательские заголовкиX-PINGOTHER, Content-Type. Наконец,Access-Control-Max-AgeДает значение в секундах для того, как долго ответы на предварительные запросы могут быть кэшированы без отправки другого запроса предварительной проверки.

После завершения предварительного запроса отправляется фактический запрос:

POST /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: https://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: https://foo.example
Pragma: no-cache
Cache-Control: no-cache

<person><name>Arun</name></person>
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain

[Some GZIP'd payload]

Многие заголовки в официальном ответе обсуждались в предыдущих статьях, и в этой статье они не будут подробно описаны.У вас все еще есть головная боль с этими концепциями HTTP?чек

учетный запрос

Самая интересная особенность XMLHttpRequest или Fetch и CORS — возможность выдавать HTTP-куки и HTTP-аутентификацию.凭证просить. По умолчанию браузер не будет отправлять учетные данные в межсайтовых вызовах XMLHttpRequest или Fetch. При вызове объекта XMLHttpRequest или конструктора запроса необходимо установить определенный флаг.

В приведенном ниже примере изначально изhttp://foo.exampleЗагруженный контент для файлов cookie с установленными файлами cookiehttp://bar.otherРесурс на foo.example делает простой запрос GET, возможный код на foo.example выглядит следующим образом

const invocation = new XMLHttpRequest();
const url = 'http://bar.other/resources/credentialed-content/';
    
function callOtherDomain() {
  if (invocation) {
    invocation.open('GET', url, true);
    invocation.withCredentials = true;
    invocation.onreadystatechange = handler;
    invocation.send(); 
  }
}

В строке 7 показан флаг XMLHttpRequest, который необходимо установить для выполнения вызовов с использованием файлов cookie. По умолчанию звонки выполняются без файлов cookie. Поскольку это простой запрос GET, предварительной проверки не будет, но браузер отклонит любой ответ без учетных данных Access-Control-Allow-Credentials: заголовок имеет значение true, что означает, что ответ не вернет содержимое веб-страницы.

Вышеупомянутый запрос может быть представлен следующим рисунком

Вот пример обмена между клиентом и сервером:

GET /resources/access-control-with-credentials/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Referer: http://foo.example/examples/credential.html
Origin: http://foo.example
Cookie: pageAccess=2
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:34:52 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 106
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain


[text/plain payload]

Строка 10 выше содержит указатели наhttp://bar.otherсодержимое файла cookie, но если bar.other не начинается сAccess-Control-Allow-Credentials:trueответ (строка 5 ниже), ответ будет проигнорирован, а содержимое, возвращенное веб-сайтом, не может быть использовано.

Запрос учетных данных и подстановочных знаков

При ответе на запрос учетных данных сервер ДОЛЖЕНAccess-Control-Allow-Credentialsукажите источник в , вместо того, чтобы писать напрямую*подстановочный знак

Поскольку заголовок запроса в приведенном выше примере кода содержит заголовок Cookie, еслиAccess-Control-Allow-Credentialsуказанный подстановочный знак*Если это так, запрос не будет выполнен.

Обратите внимание, что в приведенном выше примереSet-CookieЗаголовки ответа также имеют другой набор значений, который в случае сбоя вызовет исключение (в зависимости от используемого API).

###Заголовки ответа HTTP

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

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Credentials
  • Access-Control-Allow-Headers
  • Access-Control-Allow-Methods
  • Access-Control-Expose-Headers
  • Access-Control-Max-Age
  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Origin

Access-Control-Allow-Origin

Access-Control-Allow-Origin— это заголовок ответа HTTP, указывающий, может ли ответ совместно использовать ресурсы с данным источником. Access-Control-Allow-Origin Указание одного ресурса указывает браузеру разрешить указанному источнику доступ к ресурсу. Для запросов без учетных данных*Подстановочный знак, который указывает браузеру разрешить доступ к ресурсу любому источнику.

Например, если вы хотите разрешить источникуhttps://mozilla.orgРесурсы доступа к коду можно использовать следующими указанными методами

Access-Control-Allow-Origin: https://mozilla.org
Vary: Origin

Если сервер указывает один источник вместо*подстановочный знак, сервер также должен включить этот источник в заголовок ответа Vary.

Access-Control-Allow-Credentials

Access-Control-Allow-Credentials— это заголовок ответа HTTP, который сообщает браузеру, следует ли предоставлять ответ интерфейсному коду JavaScript, когда включен запрос учетных данных ( Request.credentials ).

Тогда вы спроситеRequest.credentialsЧто это? Не волнуйтесь, я покажу вам Прежде всего, давайте посмотрим, что такое Запрос.

По сути, Request — это класс интерфейса к Fetch API, представляющий запрос ресурса. Обычно существует два способа создания объекта запроса.

  • Создайте объект Request с помощью конструктора Request().
  • Его также можно создать с помощью операции API FetchEvent.request.

Опять же, что означает Request.credentials, доступное только для чтения свойство Credentials интерфейса Request указывает, должен ли пользовательский агент отправлять файлы cookie из других доменов в случае междоменного запроса. (Подробности см. в методах других объектов Request.developer.Mozilla.org/en-US/docs/…

При отправке запроса в режиме учетных данных включает (Request.credentials), браузер будет предоставлять ответ интерфейсному коду JavaScript только в том случае, если значение Access-Control-Allow-Credentials равно true.

Access-Control-Allow-Credentials: true

Полномочия обычно включаютфайлы cookie, заголовки аутентификации и клиентские сертификаты TLS

При использовании как часть ответа на предварительный запрос указывает, можно ли сделать фактический запрос с учетными данными. Обратите внимание на простыеGETЗапрос не будет предварительно проверяться.

Вы можете обратиться к практическому примеруу-у-у. Краткое описание.com/afraid/EA485 ох 566…

Access-Control-Allow-Headers

Access-Control-Allow-Headers— это заголовок ответа, который используется в ответ на предварительные запросы, какие заголовки HTTP он может использовать при выполнении фактического запроса.

Пример

  • настраиваемый заголовок

Вот пример заголовка Access-Control-Allow-Headers. Это указывает на то, что помимо заголовков запросов, перечисленных как CROS Safe, запросы CROS к серверу также поддерживаютX-Custom-Headerпользовательских заголовков.

Access-Control-Allow-Headers: X-Custom-Header
  • несколько заголовков

В этом примере показано, как Access-Control-Allow-Headers может использовать несколько заголовков.

Access-Control-Allow-Headers: X-Custom-Header, Upgrade-Insecure-Requests
  • Обход других ограничений

Хотя CORS-безопасные заголовки запросов всегда разрешены и, как правило, их не нужно перечислять в Access-Control-Allow-Headers, их перечисление в любом случае позволит обойти другие применимые ограничения.

Access-Control-Allow-Headers: Accept

Здесь вам может быть интересно, какие заголовки безопасности перечислены в CORS? (Не утомляйтесь, это просто хлопотно)

иметь следующееПринять, Accept-Language, Content-Language, Content-Type, нет необходимости отправлять предварительный запрос в контексте CORS тогда и только тогда, когда включены эти заголовки.

Access-Control-Allow-Methods

Access-Control-Allow-MethodsТакже заголовок ответа, который указывает, какие методы доступа к ресурсу могут использовать предварительный запрос. Например

Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Methods: *

Access-Control-Expose-Headers

Заголовки ответа Access-Control-Expose-Headers указывают, какие заголовки могут быть представлены как часть ответа. По умолчанию отображаются только 6 заголовков ответов, совместимых с CORS, а именно

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

Если вы хотите, чтобы клиенты могли получить доступ к другим заголовкам, они должны быть перечислены с использованием заголовка Access-Control-Expose-Headers. Ниже приведен пример

Чтобы выставить небезопасные заголовки запросов в списке запросов, вы можете указать следующее:

Access-Control-Expose-Headers: Content-Length

Чтобы дополнительно отображать пользовательские заголовки, такие как X-Kuma-Revision, можно указать несколько заголовков, разделенных запятыми.

Access-Control-Expose-Headers: Content-Length, X-Kuma-Revision

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

Access-Control-Expose-Headers: *

Однако это не будет подстановочным знакомAuthorizationзаголовок, поэтому, если вам нужно выставить его, вам нужно указать его явно

Access-Control-Expose-Headers: *, Authorization

Access-Control-Max-Age

Заголовок ответа Access-Control-Max-Age указывает, как долго результаты предварительного запроса могут кэшироваться, например.

Access-Control-Max-Age: 600 

Указывает, что предварительные запросы могут кэшироваться в течение 10 минут.

Access-Control-Request-Headers

Браузеры используют заголовок запроса Access-Control-Request-Headers при выполнении предварительного запроса, чтобы сообщить серверу, какие HTTP-заголовки клиент может отправить при выполнении фактического запроса.

Access-Control-Request-Headers: X-PINGOTHER, Content-Type

####Access-Control-Request-Method

Точно так же заголовок ответа Access-Control-Request-Method сообщает серверу, какой метод HTTP использовать при выполнении предварительного запроса. Этот заголовок обязателен,Поскольку предварительные запросы всегда являются ВАРИАНТАМИ, и с использованием метода, отличного от фактического запроса.

Access-Control-Request-Method: POST

Origin

Заголовок запроса Origin указывает источник совпадения, он не содержит никакой информации, только имя сервера, он отправляется с запросами CORS, а также запросами POST, он аналогиченRefererзаголовок, но в отличие от этого заголовка, он не раскрывает весь путь. Например

Origin: https://developer.mozilla.org

HTTP-условный запрос

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

в общем

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

  • за安全метод, какGET, Ресурс, используемый для запроса документа, ресурс документа отправляется обратно только тогда, когда выполняется условие условного запроса, поэтому этот метод может сэкономить пропускную способность.

Каков безопасный метод для HTTP,Безопасный способ - это тот, который не меняет состояние сервера., другими словами, если метод является только операцией только для чтения, то это должен быть безопасный метод, скажем, запрос GET, это должен быть безопасный метод, потому что он только запрашивает ресурс. Несколько распространенных методов, безусловно, безопасны, ониПОЛУЧИТЬ, ГОЛОВА и ВАРИАНТЫ. Все безопасные методы幂等的(Что, черт возьми, означает идемпотент?) Но не все идемпотентные методы безопасны, например, PUT и DELETE идемпотентны, но не безопасны.

Идемпотентность: HTTP является идемпотентным, если один и тот же клиент выполняет один или несколько HTTP-запросов и получает один и тот же результат. (На этот раз мы не будем углубляться в идемпотентность)

  • за非安全методы, такие как PUT, могут использовать условные запросы для передачи документов только в том случае, если исходный документ совпадает с ресурсом, хранящимся на сервере. (Метод PUT обычно используется для передачи файлов, как и загрузка файлов по протоколу FTP)

проверять

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

  • Дата последнего изменения документа
  • Непрозрачная строка, однозначно идентифицирующая каждую версию, называемая тегом объекта илиEtag.

Сравнивать два ресурса для одной и той же версии немного сложно, в зависимости от контекста есть две проверки на равенство

  • Когда ожидается побайтовое сравнение, например, при возобновлении загрузки, используйте强 Etagаутентификация
  • Когда пользовательскому агенту необходимо сравнить, имеют ли два ресурса одинаковый контент, используйте若 Etagаутентификация

Протокол HTTP используется по умолчанию强验证, который указывает, когда происходит слабая проверка

строгая аутентификация

Строгая проверка гарантирует, что字节Проверка уровня, строгая проверка очень строгая и может быть трудно гарантировать на уровне сервера, но она может гарантировать, что данные не будут потеряны в любое время, но такая проверка теряет производительность.

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

слабая проверка

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

Ниже показано, как Etag реализует сильную и слабую проверку.

Заголовок ответа Etag特定版本, что делает кэширование более эффективным и экономит полосу пропускания, поскольку веб-серверу не нужно повторно отправлять полный ответ, если кэшированное содержимое не изменилось. Кроме того, Etags может предотвратить одновременное обновление ресурсов и перезапись друг друга.

Если ресурс по указанному URL-адресу изменяется, необходимо создать новый.Etagзначения, сравнивая их, чтобы определить, совпадают ли два представления ресурса.

Существует два вида значений Etag: сильный Etag и слабый Etag;

  • Сильное значение Etag, независимо от того, насколько тонкие изменения сущности изменяют свое значение, общее представление выглядит следующим образом.
Etag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
  • Слабое значение Etag, слабое значение Etag используется только для указания того, одинаковы ли ресурсы. Значение Etag будет изменяться только при изменении, если ресурс существенно изменился. В этом случае W/ добавляется к началу значения поля.
Etag: W/"0815"

Давайте подробно обсудим связь между заголовком условного запроса и Etag.

условный запрос

Основные заголовки, включенные в условный запрос, следующие:

  • If-Match
  • If-None-Match
  • If-Modified-Since
  • If-Unmodified-Since
  • If-Range

If-Match

заGETиPOSTспособ, сервер работает только с перечисленнымиEtag(响应标头)Запрошенный ресурс возвращается только тогда, когда один из них совпадает. Вот новое словоEtag, мы поговорим об использовании Etag позже. для чего-то вродеPUTи другие небезопасные методы, и в этом случае он просто загрузит ресурс.

Ниже приведены два распространенных случая

  • заGETиPOSTметод, будет использоваться в сочетанииRangeзаголовок, который гарантирует, что область вновь отправленного запроса такая же, как и ресурс предыдущего запроса, если он не совпадает, он вернет416отклик.
  • Для других методов, особенноPUTметод,If-MatchЧтобы предотвратить потерю обновлений, сервер сравнивает значение поля If-Match со значением Etag ресурса и выполняет запрос, только если они совпадают. В противном случае возвращается ответ с кодом состояния 412 Precondition Failed. Например
If-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d"
If-Match: *

If-None-Match

условный запрос, связанный сIf-Matchимеет обратный эффект только тогда, когдаIf-None-Matchзначение поля сEtagКогда значения не совпадают, запрос может быть обработан. заGETиHEAD, только если сервер не соответствует данному ресурсуEtag, сервер вернется200 OKкак ответ. Для других методов запрос будет обработан только в том случае, если Etag последнего существующего ресурса не соответствует ни одному из перечисленных значений.

когдаGETиPOSTпослалIf-None-MatchиEtagПри совпадении сервер возвращает304.

If-None-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d"
If-None-Match: W/"67ab43", "54ed21", "7892dd"
If-None-Match: *

If-Modified-Since

If-Modified-SinceЭто часть условного запроса HTTP. Только после указанной даты сервер изменяет ресурсы, необходимые для запроса, и возвращает ответ 200 OK. Если сервер не изменил содержимое после указанной даты, ответ вернет304и без какого-либо тела ответа. If-Modified-Since можно использовать толькоGETиHEADпросить.

Когда If-Modified-Since используется в сочетании с If-None-Match, оно игнорируется, если только сервер не поддерживает If-None-Match. Обычно выражается следующим образом

If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT 

Примечание. Это среднее время по Гринвичу. Даты HTTP всегда выражаются по Гринвичу, а не по местному времени.

If-Range

If-RangeЭто также условный запрос, если условие выполнено (значение If-Range соответствует значению Etag или обновленной дате и времени), будет выдан запрос диапазона, в противном случае будут возвращены все ресурсы. Его общее представление выглядит следующим образом

If-Range: Wed, 21 Oct 2015 07:28:00 GMT 
If-Range: bfc13a64729c4290ef5b2c2730249c88ca92d82d

If-Unmodified-Since

If-Unmodified-SinceЗаголовок HTTP-запроса также является условным запросом, сервер вернет запрошенный ресурс только в том случае, если он не был изменен после указанной даты. Если обновление произошло после указанной даты и времени, то с кодом состояния412 Precondition Failedвернулся в качестве ответа.

If-Unmodified-Since: Wed, 21 Oct 2015 07:28:00 GMT 

Пример условного запроса

обновление кеша

Самый распространенный пример условного запроса это обновление кеша, если кеш пуст или кеша нет, то200 OKСтатус запрошенного ресурса отправляется обратно. Как показано ниже

Клиент не отправляет запрос в первый раз, кеш пуст и условный запрос отсутствует, после получения запроса от клиента сервер устанавливает валидаторLast-ModifiedиEtagтеги и отправить оба тега обратно клиенту вместе с ответом.

В следующий раз, когда клиент отправит тот же запрос, он будет извлечен прямо из кеша, и пока срок действия кеша не истек, на сервер не поступит новый запрос на повторную загрузку ресурса. Однако по истечении срока действия кэша клиент не использует кэшированное значение напрямую, а выполняет условный запрос. Значение валидатора используется какIf-Modified-SinceиIf-MatchПараметры заголовка.

После истечения срока действия кеша клиент повторно инициирует запрос.После того, как сервер получает запрос, он обнаруживает, что если ресурс не изменился, сервер отправит обратно304 Not Modifiedответ, который снова очищает кеш и позволяет клиенту использовать кешированный ресурс. Несмотря на то, что существует двусторонняя передача ответа/запроса, которая потребляет некоторые ресурсы, это более эффективно, чем повторная передача всего ресурса по сети.

Если ресурс изменился, сервер просто возвращает ответ 200 OK с новой версией ресурса, как если бы не было условного запроса, и клиент повторно использует новый ресурс, с этой точки зрения,Кэширование является предварительным условием для условных запросов.

http

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

Серверы, поддерживающие возобновляемую загрузку, отправляютAccept-RangesЗаголовок транслирует это сообщение, и как только это происходит, клиент можетRangesзаголовок для возобновления загрузки

Здесь у вас могут возникнуть вопросыRangesиContent-Rangeчто это, объясни

Range

RangeЗаголовки HTTP-запроса указывают, что сервер должен возвращать ресурсы для указанной части документа, Range может быть запрошен одновременно для возврата нескольких частей, и сервер будет возвращать эти ресурсы в каждом документе. Если сервер возвращается успешно, он вернет ответ 206; если диапазон диапазона недействителен, сервер вернет416 Range Not SatisfiableОшибка; сервер МОЖЕТ также игнорировать заголовок Range и возвращать в ответ 200.

Range: bytes=200-1000, 2000-6576, 19000-

Другое выражение

Range: bytes=0-499, -500 

Они представляют собой первые 500 байт и последние 500 байт запроса соответственно, и если диапазоны перекрываются, сервер может отклонить запрос.

Content-Range

Заголовок ответа HTTP Content-Range устанавливается для запросов диапазона, а поле заголовка используется при возврате ответа.Content-Range, который сообщает клиенту, какая часть объекта ответа соответствует запросу клиента. Поля указаны в байтах. Его общее представление выглядит следующим образом

Content-Range: bytes 200-1000/67589 

Приведенный выше код означает, что из всех67589возвращено в байтах200-1000байты контента

тогда вышеContent-RangeВы должны знать, что это значит

断点续传Принцип относительно прост, но при таком подходе есть потенциальная проблема: если обновление ресурса производится между двумя загрузками ресурса, полученная область будет соответствовать двум разным версиям ресурса, а окончательный документ будет поврежден.

Чтобы этого не произошло, используйте条件请求. Для диапазонов есть два способа сделать это. Один из способов - использоватьIf-Modified-SinceиIf-Match, если предварительное условие не выполнено, сервер возвращает ошибку, после чего клиент перезагружается с самого начала.

Даже если это работает, при изменении ресурса документа добавляется дополнительная информация.响应/请求обмен. Это снижает производительность, и HTTP имеет специальные заголовки, чтобы избежать этого.If-Range.

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

Избегайте потери обновлений с помощью оптимистичной блокировки

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

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

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

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

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

Это используетIf-MatchилиIf-Unmodified-Sinceреализован заголовок. Если Etag не соответствует исходному файлу или если файл был изменен с момента его получения, измените значение на Запретить обновление и отобразите412 Precondition FailedОшибка.

HTTP Cookies

Файлы cookie в протоколе HTTP включаютWeb Cookieи浏览器 Cookie, представляющий собой небольшой фрагмент данных, который сервер отправляет веб-браузеру. Файл cookie, отправленный сервером в браузер, сохраненный браузером и отправленный на сервер со следующим запросом. Обычно он используется, чтобы определить, исходят ли два запроса от одного и того же браузера, например, если пользователь остается в системе.

Механизм HTTP Cookie является дополнением и улучшением протокола HTTP без сохранения состояния.

Файлы cookie в основном используются для следующих трех целей.

  • 会话管理

Логин, корзина, счет в игре или что-то еще, что сервер должен помнить.

  • 个性化

Пользовательские настройки, темы и другие настройки

  • 追踪

Записывайте и анализируйте поведение пользователей

Раньше файлы cookie использовались для общего хранения данных на стороне клиента. Хотя это законно, поскольку это единственный способ хранения данных на стороне клиента, сегодня рекомендуются современные API-интерфейсы хранилища. Файлы cookie отправляются с каждым запросом, поэтому они могут снизить производительность (особенно при мобильных подключениях для передачи данных). Современные API для хранилища на стороне клиента — это API веб-хранилища (localStorage и sessionStorage) и IndexedDB.

Создать файлы cookie

При получении HTTP-запроса от клиента сервер может отправить ответSet-Cookieзаголовки, файлы cookie обычно сохраняются браузером, а затем файлы cookie отправляются на сервер вместе с заголовками HTTP. Можно указать дату истечения срока действия или продолжительность, после которой файлы cookie больше не будут отправляться. Кроме того, можно установить ограничения для определенных доменов и путей, тем самым ограничивая, куда отправляются файлы cookie.

Set-Cookie и заголовок Cookie

Set-CookieЗаголовок ответа HTTP отправляет файл cookie с сервера пользовательскому агенту. Ниже приведен пример отправки файла cookie

HTTP/2.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[page content]

Этот заголовок говорит клиенту сохранить файл cookie

Теперь при каждом новом запросе к серверу браузер будет отправлять все ранее сохраненные файлы cookie обратно на сервер, используя заголовок Cookie.

GET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

Существует три основных категории файлов cookie:会话Cookie,永久CookieиCookie的 Secure 和 HttpOnly 标记, следующее представит

Сеансовые файлы cookie

В приведенном выше примере создается файл cookie сеанса.Функция файла cookie сеанса заключается в том, что файл cookie будет удален при закрытии клиента, поскольку в нем не указаны директивы Expires или Max-Age. Эти две команды должны быть вам знакомы, когда вы видите их здесь.

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

Постоянные файлы cookie

Срок действия постоянных файлов cookie истекает не при закрытии клиента, а по истечении определенной даты (Expires) или определенного периода времени (Max-Age). Например

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

Флаги Secure и HttpOnly для файлов cookie

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

Роль HttpOnly

  • Отсутствие атрибута HttpOnly в сеансовом файле cookie приведет к тому, что злоумышленник получит информацию о пользовательском файле cookie через программу (JS-скрипт, апплет и т. д.), что приведет к утечке информации о пользовательском файле cookie и повысит угрозу перекрестной атаки злоумышленника. -атака с использованием скриптов сайта.

  • HttpOnly — это расширение Майкрософт для файлов cookie, которое указывает, можно ли получить доступ к файлу cookie с помощью сценариев на стороне клиента.

  • Если для атрибута HttpOnly в файле cookie не задано значение true, файл cookie может быть украден. Украденные файлы cookie могут содержать конфиденциальную информацию, которая идентифицирует пользователя сайта, например идентификаторы сеансов ASP.NET или билеты проверки подлинности с помощью форм, и злоумышленники могут воспроизвести украденные файлы cookie, чтобы выдать себя за пользователя или получить конфиденциальную информацию, выполнить межсайтовые сценарии. атаки и многое другое.

Объем файлов cookie

DomainиPathИдентификатор определяет область действия файла cookie: то есть, на какие URL-адреса должен быть отправлен файл cookie.

DomainОпределяет, какие хосты могут принимать файлы cookie. Если не указано, по умолчанию используется текущий хост (Не содержит поддоменов). если указаноDomain, он обычно включает поддомены.

Например, если вы установитеDomain=mozilla.org, файл cookie также включен в поддомен (например,developer.mozilla.org).

Например, установитеPath=/docs, все следующие адреса будут совпадать:

  • /docs
  • /docs/Web/
  • /docs/Web/HTTP

Ссылка на статью:

developer.mozilla.org/en-US/docs/

woohoo.brief.com/afraid/5 из 41 из 536 из…

Woohoo. Я 3schools.com/PHP/default…

у-у-у. Краткое описание.com/afraid/EA485 ох 566…

blog.CSDN.net/QQ_38098125…