(Рекомендуемое интенсивное чтение) Душа HTTP, консолидируйте свою систему знаний HTTP

JavaScript опрос

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

001. Какова структура HTTP-сообщения?

Для TCP он делится на две части во время передачи:TCP-заголовока такжечасть данных.

И HTTP тоже похожheader + bodyструктура, в частности:

起始行 + 头部 + 空行 + 实体

из-за http请求报文а также响应报文Есть определенные отличия, поэтому мы вводим их отдельно.

стартовая линия

Для сообщения запроса стартовая строка выглядит так:

GET /home HTTP/1.1

то естьметод + путь + версия http.

Для ответного сообщения начальная строка обычно выглядит так:

HTTP/1.1 200 OK

Стартовая строка ответного сообщения также называется状态行. Зависит отверсия http, код состояния и причинаОн состоит из трех частей.

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

голова

Показать расположение заголовков запроса и ответа в сообщении:

Будь то заголовок запроса или заголовок ответа, есть довольно много полей, и они включаютhttpФункций очень много, поэтому я не буду их все здесь перечислять, сосредоточимся на формате этих полей заголовка:

    1. Имена полей не чувствительны к регистру
    1. Имя поля не допускает пробелов и символов подчеркивания._
    1. Имя поля должно сопровождатьсяНезамедлительно после:

пустая строка

важно различать头部а также实体.

В: Что делать, если в середине заголовка намеренно добавлена ​​пустая строка?

Затем содержимое после пустой строки рассматривается как сущность.

организация

Это конкретные данные, т.bodyчасть. соответствующий сообщению запроса请求体, соответствующий ответному сообщению响应体.

002. Как понять метод запроса HTTP?

Какие способы запроса?

http/1.1Указаны следующие методы запроса (обратите внимание, что все они пишутся с заглавной буквы):

  • GET: обычно используется для получения ресурсов
  • HEAD: Получить метаинформацию о ресурсе
  • POST: Отправить данные, то есть загрузить данные
  • ПОСТАВИТЬ: изменить данные
  • УДАЛИТЬ: удалить ресурс (почти никогда не используемый)
  • CONNECT: установить туннель подключения для прокси-сервера
  • ВАРИАНТЫ: Перечислите методы запросов, которые можно выполнять с ресурсом для междоменных запросов.
  • TRACE: трассировка пути передачи запроса-ответа

В чем разница между GET и POST?

Первое и самое интуитивное — это семантическая разница.

Тогда есть некоторые конкретные различия:

  • оттайникС точки зрения GET-запросы будут активно кэшироваться браузером, оставляя исторические записи, в то время как POST-запросы не будут по умолчанию.
  • откодированиеGET может быть закодирован только в URL-адресе и может принимать только символы ASCII, в то время как POST не имеет ограничений.
  • отпараметрС точки зрения GET вообще помещается в URL, поэтому небезопасно, а POST помещается в тело запроса, что больше подходит для передачи конфиденциальной информации.
  • отидемпотентностьУгол,GETдаидемпотент, покаPOSTнет. (幂等означает, что выполняется одна и та же операция, и результат тот же)
  • отTCPС точки зрения, запрос GET будет отправлять сообщение запроса за один раз, в то время как POST будет разделен на два TCP-пакета, сначала будет отправлена ​​часть заголовка, если сервер ответит 100 (продолжить), затем тело часть будет отправлена. (Fire FoxЗа исключением браузера, его POST-запрос отправляет только TCP-пакет)

003: Как понимать URI?

URI, полное имя (Uniform Resource Identifier), т.е.Единый идентификатор ресурса, его роль очень проста, то есть различать разные ресурсы в Интернете.

Однако это не то, что мы часто говорим网址, URL относится кURL, по фактуURIсодержитURNа такжеURLОбе части, из-за популярности URL-адресов, URI по умолчанию обрабатываются как URL-адреса.

Структура URI

Истинная наиболее полная структура URI такова.

У вас могут возникнуть сомнения, кажется, что это не то, что вы обычно видите! Не волнуйтесь, давайте демонтируем их один за другим.

schemeУказывает имя протокола, напримерhttp, https, fileи т.п. должны сопровождаться://связаны вместе.

user:passwd@ представляет информацию о пользователе при входе на хост, но это очень небезопасно, не рекомендуется и редко используется.

host:portУказывает имя хоста и порт.

pathУказывает путь запроса, отмечая расположение ресурса.

queryПредставляет параметры запроса, которыеkey=valВ этой форме несколько пар ключ-значение используются между&разделены.

fragmentПредставляет ресурс внутри ресурса, расположенного по URIЯкорь, браузер может перейти к соответствующей позиции на основе этой точки привязки.

Например:

https://www.baidu.com/s?wd=HTTP&rsv_spt=1

В этом URIhttpsкоторыйschemeчасть,www.baidu.comдляhost:portраздел (обратите внимание, что порты по умолчанию для http и https — 80, 443 соответственно),/sдляpathчасть, покаwd=HTTP&rsv_spt=1то естьqueryчасть.

Кодировка URI

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

Таким образом, URI вводит编码механизм, который всене-ASCII-символыа такжеразделительПреобразуйте в шестнадцатеричное байтовое значение, затем добавьте%.

Например, пробелы экранируются как%20,троичныйубегает как%E4%B8%89%E5%85%83.

004: Как понять коды состояния HTTP?

RFC указывает, что код состояния HTTPтри цифры, делится на пять категорий:

  • 1xx: Указывает, что в настоящее время находится промежуточное состояние обработки протокола и требуются дальнейшие операции.
  • 2xx: Указывает статус успеха.
  • 3xx: Состояние перенаправления, расположение ресурса изменилось и требует повторного запроса.
  • 4xx: Сообщение запроса неверно.
  • 5xx: Произошла ошибка на стороне сервера.

Далее мы проанализируем конкретные коды состояния здесь один за другим.

1xx

101 Switching Protocols. существуетHTTPобновитесь доWebSocket, если сервер соглашается на изменение, отправляется код состояния 101.

2xx

200 OKЭто наиболее распространенный код состояния успеха. Обычно данные помещаются в тело ответа.

204 No ContentЗначение такое же, как и у 200, но после заголовков ответа нет данных тела.

206 Partial ContentКак следует из названия, он представляет собой часть содержимого.Его сценарии использования включают загрузку блока HTTP и возобновление точки останова, и, конечно же, он также принесет соответствующие поля заголовка ответа.Content-Range.

3xx

301 Moved PermanentlyТо есть постоянное перенаправление, соответствующее302 Found, что является временным перенаправлением.

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

А если только временно недоступен, то верни напрямую302может быть и301Разница в том, что браузер не занимается оптимизацией кеша.

304 Not Modified: этот код состояния возвращается при согласовании попадания в кэш. смотрите подробностикеш браузера

4xx

400 Bad Request: Разработчики часто путаются и просто дают общее указание на ошибку, и не знают, что пошло не так.

403 Forbidden: На самом деле это не ошибка в сообщении запроса, а сервер запрещает доступ.Причин много, например юридический запрет и конфиденциальная информация.

404 Not Found: Ресурс не найден, что означает, что соответствующий ресурс не найден на сервере.

405 Method Not Allowed: Метод запроса не разрешен на стороне сервера.

406 Not Acceptable: Ресурс не может удовлетворить условию клиента.

408 Request Timeout: Сервер слишком долго ждал.

409 Conflict: Несколько запросов конфликтуют.

413 Request Entity Too Large: Данные в теле запроса слишком велики.

414 Request-URI Too Long: URI в строке запроса слишком велик.

429 Too Many Request: клиент отправил слишком много запросов.

431 Request Header Fields Too LargeСодержимое поля заголовка запроса слишком велико.

5xx

500 Internal Server Error: Сразу скажу, что сервер не в порядке, мы не знаем, что пошло не так.

501 Not Implemented: Указывает, что функция, запрошенная клиентом, еще не поддерживается.

502 Bad Gateway: Сам сервер в норме, но при доступе к нему ошибка, а в чем ошибка мы не знаем.

503 Service Unavailable: указывает, что сервер в настоящее время занят и временно не может ответить на услугу.

005: Кратко охарактеризовать HTTP? Каковы недостатки HTTP?

HTTP-функции

Характеристики HTTP резюмируются следующим образом:

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

  2. Надежная передача. HTTP основан на TCP/IP и, таким образом, наследует эту функцию. Это функция TCP, и она не будет подробно описана.

  3. ответ на запрос. то есть一发一收,有来有回,Конечно, реквестер и респондер находятся не только между клиентом и сервером.Если сервер выступает в качестве прокси для подключения к фоновому серверу, то этот сервер также будет выступать в роли прокси.Заявительхарактер.

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

Недостатки HTTP

нет статуса

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

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

Но в то же время некоторые другие приложения предназначены только для получения некоторых данных и не нуждаются в сохранении информации о контексте соединения.Безгражданство снижает нагрузку на сеть и становится преимуществом http.

передача открытого текста

То есть сообщение в протоколе (в основном относящееся к заголовку) использует не бинарные данные, а текстовую форму.

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

проблема с блокировкой очереди

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

006: Что вы знаете о семействе полей Accept?

дляAcceptВведение в поле сериалов разделено на четыре части:Формат данных,Метод сжатия,Поддерживаемые языкиа такженабор символов.

Формат данных

В предыдущем разделе говорилось о гибких возможностях HTTP: он поддерживает множество форматов данных, так как же клиент узнает свой формат, когда к клиенту одновременно поступает так много форматов данных?

Конечно, наименее эффективный способ — просто гадать, есть ли лучший способ? Можно прямо указать?

Ответ положительный. Но сначала нам нужно ввести стандарт -MIME(Multipurpose Internet Mail Extensions, Многоцелевое расширение электронной почты Интернета). Впервые он был использован в системах электронной почты, чтобы позволить электронным письмам отправлять данные любого типа, что также характерно для HTTP.

Таким образом, HTTP изMIME typeЧасть берется для обозначения типа данных основной части сообщения.Эти типы отражены вContent-TypeЭто поле, конечно же, для отправителя, получатель хочет получить определенный тип данных, вы также можете использоватьAcceptполе.

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

  • текст: текст/html, текст/обычный, текст/css и т. д.
  • изображение: изображение/gif, изображение/jpeg, изображение/png и т. д.
  • аудио/видео: аудио/mpeg, видео/mp4 и т. д.
  • application: application/json, application/javascript, application/pdf, application/octet-stream

Метод сжатия

Конечно, эти данные, как правило, кодируются и сжимаются, а принятый метод сжатия отражается в адресе отправителя.Content-EncodingТочно так же на поле то, какой метод сжатия принимается, отражается в приемнике.Accept-Encodingна поле. Значения этого поля следующие:

  • gzip: самый популярный на сегодняшний день формат сжатия
  • deflate: еще один известный формат сжатия
  • br: алгоритм сжатия, специально разработанный для HTTP.
// 发送端
Content-Encoding: gzip
// 接收端
Accept-Encoding: gzip

Поддерживаемые языки

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

// 发送端
Content-Language: zh-CN, zh, en
// 接收端
Accept-Language: zh-CN, zh, en

набор символов

Последнее представляет собой относительно специальное поле, которое соответствует принимающей стороне какAccept-Charset, задает допустимый набор символов, и нет соответствующегоContent-Charset, а непосредственно помещенныйContent-Typeв, сcharsetспецификация атрибута. Такие как:

// 发送端
Content-Type: text/html; charset=utf-8
// 接收端
Accept-Charset: charset=utf-8

Напоследок подытожим картинкой:

007: Как HTTP передает данные фиксированной и переменной длины?

Включения фиксированной длины

Для пакетов фиксированной длины отправитель обычно приноситContent-Length, чтобы указать длину тела пакета.

Мы используем А.nodejsСервер для имитации:

const http = require('http');

const server = http.createServer();

server.on('request', (req, res) => {
  if(req.url === '/') {
    res.setHeader('Content-Type', 'text/plain');
    res.setHeader('Content-Length', 10);
    res.write("helloworld");
  }
})

server.listen(8081, () => {
  console.log("成功启动");
})

Доступ после запуска:localhost:8081.

В браузере отображается следующее:

helloworld

Это случай с правильной длиной, как обрабатывается неправильный случай?

Попробуем уменьшить эту длину:

res.setHeader('Content-Length', 8);

Перезапустите сервис и зайдите снова.Теперь содержимое в браузере выглядит следующим образом:

hellowor

что позадиldКуда это делось? На самом деле, он прямо усекается в теле ответа http.

Затем мы пытаемся установить эту длину больше:

res.setHeader('Content-Length', 12);

В этот момент браузер отображает следующее:

Невозможно отобразить напрямую. можно увидетьContent-LengthОн играет очень важную роль в процессе передачи http, неправильные настройки могут напрямую привести к сбою передачи.

неопределенная длина

Вышеупомянутое для定长包体, то для不定长包体Как это передается?

Вот еще одно поле заголовка http, которое необходимо ввести:

Transfer-Encoding: chunked

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

  • Поле Content-Length игнорируется
  • Постоянно отправляйте динамический контент на основе длинных подключений

Мы по-прежнему используем практический пример для имитации передачи блока.Программа nodejs выглядит следующим образом:

const http = require('http');

const server = http.createServer();

server.on('request', (req, res) => {
  if(req.url === '/') {
    res.setHeader('Content-Type', 'text/html; charset=utf8');
    res.setHeader('Content-Length', 10);
    res.setHeader('Transfer-Encoding', 'chunked');
    res.write("<p>来啦</p>");
    setTimeout(() => {
      res.write("第一次传输<br/>");
    }, 1000);
    setTimeout(() => {
      res.write("第二次传输");
      res.end()
    }, 2000);
  }
})

server.listen(8009, () => {
  console.log("成功启动");
})

Эффект доступа выглядит следующим образом:

Ответ, полученный с помощью telnet, выглядит следующим образом:

Уведомление,Connection: keep-aliveа предыдущие - это строка ответа и заголовок ответа, а следующее содержимое - тело ответа. Эти две части разделены новой строкой.

Интересна структура тела ответа:

chunk长度(16进制的数)
第一个chunk的内容
chunk长度(16进制的数)
第二个chunk的内容
......
0

Наконец есть один空行Да, пожалуйста, обратите на это внимание.

Выше приведен http дляДанные фиксированной длиныа такжеданные переменной длиныспособ передачи.

008: Как HTTP обрабатывает передачу больших файлов?

Для больших файлов с сотнями M или даже G передать их все за один раз явно нереально, и будет много времени ожидания, что серьезно повлияет на пользовательский опыт. Таким образом, HTTP принимает范围请求Решение, которое позволяет клиентам запрашивать только часть ресурса.

Как поддержать

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

Accept-Ranges: none

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

Разборка поля дальности

Для клиента необходимо указать, какая часть запроса черезRangeЭто поле заголовка запроса определено, и форматbytes=x-y. Далее давайте обсудим формат записи этого диапазона:

  • 0-499Указывает от начала до 499-го байта.
  • 500- означает от 500-го байта до конца файла.
  • -100Представляет последние 100 байтов файла.

После того, как сервер получает запрос, он сначала проверяет область действия.это законно, если за пределами, то вернуться416Код ошибки, в противном случае прочитать соответствующий сегмент и вернуться206код состояния.

При этом на сервере необходимо добавитьContent-Rangeполе, формат этого поля основан на заголовке запросаRangeварьируется в зависимости от поля.

В частности, запрос单段数据и запросить多段数据, заголовки ответа не совпадают.

Например:

// 单段数据
Range: bytes=0-9
// 多段数据
Range: bytes=0-9, 30-39

Далее мы обсудим два случая отдельно.

Один кусок данных

для单段数据запрос, возвращенный ответ выглядит следующим образом:

HTTP/1.1 206 Partial Content
Content-Length: 10
Accept-Ranges: bytes
Content-Range: bytes 0-9/100

i am xxxxx

Стоит отметить, чтоContent-Rangeполе,0-9представляет собой возврат запроса,100Указывает общий размер ресурса, в котором легко разобраться.

Многосегментные данные

Далее рассмотрим случай многосегментных запросов. В результате ответ будет иметь вид:

HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=00000010101
Content-Length: 189
Connection: keep-alive
Accept-Ranges: bytes


--00000010101
Content-Type: text/plain
Content-Range: bytes 0-9/96

i am xxxxx
--00000010101
Content-Type: text/plain
Content-Range: bytes 20-29/96

eex jspy e
--00000010101--

В это время появилось очень критическое полеContent-Type: multipart/byteranges;boundary=00000010101, который представляет собой объем такой информации:

  • Запрос должен быть многосегментным запросом данных.
  • Разделитель в теле ответа — 00000010101.

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

Это инструменты для больших передач файлов HTTP HTTP.

009: Как обрабатывать отправку данных формы в HTTP?

В http существует два основных способа отправки форм, отраженных в двух разныхContent-TypeСтоимость:

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

Поскольку отправка формы обычноPOSTпросьба, редко рассматриваемаяGET, поэтому здесь мы помещаем данные, отправленные по умолчанию, в тело запроса.

application/x-www-form-urlencoded

дляapplication/x-www-form-urlencodedСодержание формы в формате имеет следующие характеристики:

  • Данные в нем будут закодированы как&пары ключ-значение с разделителями
  • символы начинаются сКодировка URLкодирование.

Такие как:

// 转换过程: {a: 1, b: 2} -> a=1&b=2 -> 如下(最终形式)
"a%3D1%26b%3D2"

multipart/form-data

дляmultipart/form-dataС точки зрения:

  • в заголовке запросаContent-Typeполе будет содержатьboundary,а такжеboundaryЗначение задается браузером по умолчанию. пример:Content-Type: multipart/form-data;boundary=----WebkitFormBoundaryRRJKeWfHPGrS4LKe.
  • Данные будут разделены на несколько частей, каждые две части разделены разделителем, и каждая часть выражения имеет тело подпакета с описанием заголовка HTTP, напримерContent-Type, будет добавлен последний разделитель--Указывает конец.

соответствующий请求体составляет:

Content-Disposition: form-data;name="data1";
Content-Type: text/plain
data1
----WebkitFormBoundaryRRJKeWfHPGrS4LKe
Content-Disposition: form-data;name="data2";
Content-Type: text/plain
data2
----WebkitFormBoundaryRRJKeWfHPGrS4LKe--

резюме

Стоит отметить, чтоmultipart/form-dataСамый большой формат:Каждый элемент формы является независимым представлением ресурса.. Кроме того, вы можете не заметить в процессе написания дела, что естьboundaryСуществование , если вы откроете инструмент захвата пакетов, вы действительно увидите, что разные элементы формы разделены Причина, по которой вы не можете почувствовать это в обычное время, заключается в том, что браузер и HTTP инкапсулируют эту серию операций для вас.

Кроме того, в реальной сцене для загрузки файлов, таких как изображения, в основном используетсяmultipart/form-dataвместоapplication/x-www-form-urlencoded, потому что нет необходимости кодировать URL, что отнимает много времени и занимает больше места.

010: Как HTTP1.1 решает проблему блокировки заголовка HTTP?

Что такое блокировка заголовка строки HTTP?

Как видно из предыдущих разделов, транспорт HTTP основан на请求-应答Сообщение должно быть отправлено и получено один раз, но стоит отметить, что задачи в нем помещаются в очередь задач для последовательного выполнения.Как только обработка запроса в голове очереди слишком медленная, обработка последующих запросов будет заблокирован.. это известноHTTP队头阻塞вопрос.

одновременные соединения

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

Но на самом деле, даже если параллельное соединение будет улучшено, оно все равно не сможет удовлетворить потребности людей в производительности.

Шардинг домена

Может ли доменное имя не иметь 6 длинных подключений одновременно? Затем я разделю еще несколько доменных имен.

Например, content1.sanyuan.com и content2.sanyuan.com.

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

011: Что вы знаете о файлах cookie?

Введение в файлы cookie

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

Для этого HTTP ввел файлы cookie. Cookie — это, по сути, небольшой текстовый файл, хранящийся в браузере в виде пар ключ-значение (его можно увидеть в столбце «Приложение» панели разработчика Chrome). Отправка запросов на одно и то же доменное имя будет содержать один и тот же файл cookie, и сервер может получить статус клиента после получения файла cookie для анализа. Сервер может передать заголовок ответаSet-Cookieполе для записи клиентуCookie. Примеры следующие:

// 请求头
Cookie: a=xxx;b=xxx
// 响应头
Set-Cookie: a=xxx
set-Cookie: b=xxx

Атрибут файла cookie

жизненный цикл

Дата истечения срока действия файла cookie может быть определенаExpiresа такжеMax-AgeДва свойства для установки.

  • Expiresкоторый过期时间
  • Max-AgeОн использует временной интервал в секундах, рассчитываемый с момента получения сообщения браузером.

Если срок действия файла cookie истекает, файл cookie будет удален и не будет отправлен на сервер.

объем

Есть также два свойства области видимости:Domainа такжеpath, ДатьCookieИмя домена и путь привязаны, перед отправкой запроса обнаруживается, что имя домена или путь не соответствуют этим двум атрибутам, поэтому куки не принесут. Стоит отметить, что для путей/Указывает, что любой путь под доменным именем может использовать файлы cookie.

связанных с безопасностью

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

Если поле cookie вывестиHttpOnly, то это означает, что он может передаваться только по HTTP-протоколу и не может быть доступен через JS, что также является важным средством предотвращения XSS-атак.

Соответственно, для предотвращения CSRF-атак также существуютSameSiteАтрибуты.

SameSiteМожно установить до трех значений,Strict,Laxа такжеNone.

a.существуетStrictВ режиме браузер полностью запрещает сторонним запросам передавать файлы cookie. например запросsanyuan.comСайт может быть толькоsanyuan.comТолько запросы в доменном имени могут содержать файлы cookie, а запросы с других веб-сайтов не могут.

b.существуетLaxрежиме, он немного свободнее, но только вget 方法提交表单состояние илиa 标签发送 get 请求Cookie могут быть перенесены в случае , но не в других случаях.

c.существуетNoneВ режиме, который является режимом по умолчанию, запросы автоматически содержат файлы cookie.

Недостатки файлов cookie

  1. Дефект емкости. Предельный размер файлов cookie составляет всего4KB, может использоваться только для хранения небольшого количества информации.

  2. недостатки производительности. Файл cookie тесно следует за доменным именем.Независимо от того, нуждается ли определенный адрес под доменным именем в этом файле cookie или нет, запрос будет содержать полный файл cookie, поэтому по мере увеличения количества запросов это фактически приведет к огромным потерям производительности, потому что запрос содержит много ненужного контента. но черезDomainа такжеPathуточнитьобъемрешать.

  3. Недостатки безопасности. Поскольку файл cookie передается в браузере и на сервере в виде простого текста, его легко перехватить нелегальными пользователями, а затем выполнить серию фальсификаций и повторно отправить на сервер в течение срока действия файла cookie, что составляет довольно опасно. Кроме того, вHttpOnlyВ случае false информация о файлах cookie может быть прочитана напрямую через JS-скрипт.

012: Как понять HTTP-прокси?

Мы знаем, что HTTP основан на请求-响应Модель протокола, как правило, к концу запрашивающего клиента, сервер отвечает.

Конечно, есть и частные случаи, то есть случай с прокси-серверами. После введения прокси сервер, действующий в качестве прокси, эквивалентен роли посредника: для клиента он появляется как отвечающий сервер, для исходного сервера он появляется как клиент, инициирующий запрос иДвойная идентичность.

Для чего используется прокси-сервер?

Функция

  1. Балансировка нагрузки. Запрос клиента сначала достигнет прокси-сервера, и клиент не знает, сколько существует исходных серверов и IP-адресов. Поэтому после того, как прокси-сервер сможет получить запрос, он может распределить его по разным исходным серверам по определенному алгоритму, чтобы нагрузка на каждый исходный сервер была максимально равномерной. Конечно, таких алгоритмов много, в том числеслучайный алгоритм,голосование,Согласованный хэш,LRU(最近最少使用)Подождите, но эти алгоритмы не являются предметом этой статьи, вы можете изучить их самостоятельно, если вам интересно.

  2. безопасность. использоватьстук сердцаМеханизм отслеживает серверы в фоновом режиме и отключает кластер, как только обнаруживается неисправная машина. Кроме того, работа прокси-сервера заключается в фильтрации восходящих и нисходящих данных и ограничении потока незаконных IP-адресов.

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

Связанные поля заголовка

Via

Прокси-сервер должен идентифицировать себя и оставлять свои следы в передаче HTTP, что мне делать?

пройти черезViaполе для записи. Например, сейчас посередине два прокси-сервера, после того, как клиент отправит запрос, он пройдет такой процесс:

客户端 -> 代理1 -> 代理2 -> 源服务器

После того, как исходный сервер получит запрос, он请求头Получите это поле:

Via: proxy_server1, proxy_server2

Когда исходный сервер ответит, клиент в конечном итоге получит это响应头:

Via: proxy_server2, proxy_server1

можно увидеть,ViaПорядок, в котором находятся прокси, — это порядок, в котором сообщения передаются в HTTP-транспорте.

X-Forwarded-For

Буквально означает为谁转发, который записываетЗаявительизIPадрес (примечание иViaдифференцировать,X-Forwarded-ForЗапись - это IP-запрос).

X-Real-IP

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

Соответственно существуют иX-Forwarded-Hostа такжеX-Forwarded-Proto, запишите отдельноклиент(обратите внимание, что это не включает прокси)域名а также协议名.

Проблемы с X-переадресованными

Как вы могли видеть ранее,X-Forwarded-ForВ этом поле записывается IP-адрес запрашивающей стороны, что означает, что имя этого поля будет меняться каждый раз, когда оно проходит через другой прокси.客户端прибыть代理1, это поле - IP клиента, из代理1прибыть代理2, это поле становится IP-адресом прокси 1.

Но это создает две проблемы:

  1. Это означает, что прокси должен проанализировать заголовок HTTP-запроса, а затем изменить его, что медленнее, чем прямая пересылка данных.

  2. В процессе шифрования HTTPS-соединения исходное сообщение не может быть изменено.

в результате этого代理协议, обычно используйте версию с открытым текстом, просто добавьте текст в этом формате над строкой HTTP-запроса:

// PROXY + TCP4/TCP6 + 请求方地址 + 接收方地址 + 请求端口 + 接收端口
PROXY TCP4 0.0.0.1 0.0.0.2 1111 2222
GET / HTTP/1.1
...

это решитX-Forwarded-Forпринес проблемы.

013: Как понять HTTP-кеширование и кэширующие прокси?

о强缓存а также协商缓存содержание, у меня уже естьМожете ли вы рассказать о кэшировании браузера?После детального анализа итоги такие:

сначала черезCache-ControlУбедитесь, что надежное кэширование доступно

  • Если у вас есть сильный буфер, используйте напрямую
  • В противном случае войти в кеш согласования, то есть отправить HTTP-запрос, и сервер передаетIf-Modified-SinceилиIf-None-MatchЭтиусловный запросПоле для проверки обновления ресурса
    • Если ресурс обновлен, вернуть ресурс и код состояния 200.
    • В противном случае верните 304, сообщив браузеру получить ресурс непосредственно из кэша

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

Зачем генерировать кеш прокси?

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

таким образом введенкеширующий проксиМеханизмы. Позволять代理服务器Возьмите на себя часть HTTP-кэша на стороне сервера после истечения срока действия кеша на стороне клиента.рядом, поблизостиПолучите его из кеша прокси и запрашивайте исходный сервер только по истечении срока действия кеша прокси, что может значительно снизить нагрузку на исходный сервер при огромном трафике.

Итак, как именно кэширующий прокси это делает?

В целом, агент управления кешем разделяется на две части, одинИсходный серверКонечный контроль, частьклиентконтроль.

Управление кешем исходного сервера

частный и общественный

В заголовке ответа исходного сервера он добавитCache-ControlЭто поле является кешированным управляющим полем, тогда его значение может быть добавлено.privateилиpublicУказывает, разрешать ли кэширование прокси-сервера, первое запрещено, второе разрешено.

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

proxy-revalidate

must-revalidateозначаетклиентКогда срок действия кеша истечет, перейдите на исходный сервер, чтобы получить его, иproxy-revalidateозначаетпрокси-серверПо истечении срока действия кеша он получается с исходного сервера.

s-maxage

sдаshareЭто означает, что он ограничивает время хранения кеша на прокси-сервере и ограничивает время кеша клиента.max-ageне конфликт.

Поговорив об этих полях, возьмем небольшой пример: исходный сервер добавляет в заголовок ответа такое поле:

Cache-Control: public, max-age=1000, s-maxage=2000

Это эквивалентно тому, что исходный сервер говорит: «Мой ответ разрешен к кэшированию прокси-сервером. Срок действия кеша клиента истек, и он переносится на прокси, а время кеша на клиенте составляет 1000 секунд, а время кеша в прокси сервер 2000 с.

Управление кешем на стороне клиента

max-stale и min-fresh

В заголовок запроса клиента эти два поля можно добавить для выполнения кэширования на прокси-сервере.терпимыйа такжеограничениеработать. Например:

max-stale: 5

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

Другой пример:

min-fresh: 5

Указывает, что кеш прокси нуждается в определенной степени свежести. Не ждите, пока истечет срок действия кеша, прежде чем его использовать.5 секунд до истечения срока действияВ противном случае вы не можете получить его.

only-if-cached

Добавление этого поля указывает, что клиент будет принимать только кеш прокси, а не ответ исходного сервера. Если кеш прокси недействителен, вернитесь напрямую504(Gateway Timeout).

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

014: Что такое междоменный домен? Как браузер перехватывает ответ? Как решить?

В режиме разработки, где front-end и back-end разделены, часто возникают междоменные проблемы, то есть отправляется Ajax-запрос и сервер успешно отвечает, но front-end просто не может получить ответ. Далее мы подробно обсудим этот вопрос.

что такое кросс домен

Напомним URI состоит из:

браузер следитьТа же политика происхождения(scheme(协议),host(主机)а такжеport(端口)подобные同源). Негомологичные сайты имеют следующие ограничения:

  • Вы не можете читать и изменять DOM друг друга
  • Не читать доступ к файлам cookie друг друга, IndexDB и LocalStorage
  • Ограничьте запросы XMLHttpRequest. (Следующие темы посвящены этому)

Когда браузер отправляет запрос Ajax на целевой URI, если текущий URL-адрес и целевой URL-адрес имеют разное происхождение, возникает междоменное взаимодействие, которое называется跨域请求.

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

Первое, что нужно знать, это то, что браузер является многопроцессорным, Взяв в качестве примера Chrome, состав процесса выглядит следующим образом:

Двигатель рендеринга WebKitа такжедвигатель V8находятся в процессе рендеринга.

когдаxhr.sendПри вызове, то есть когда запрос Ajax готов к отправке, фактически выполняется только процесс рендеринга. Чтобы хакеры не трогали системные ресурсы через скрипты, браузер загружает каждый процесс рендеринга в песочницу, а для того, чтобы микросхема ЦП не существовала постоянноSpectreа такжеMeltdownлазейки, взятые站点隔离Средства назначения песочниц каждому отдельному сайту (разные доменные имена первого уровня), не мешающие друг другу. Подробнее см.Видео презентации команды безопасности Chromium на YouTube.

Процесс рендеринга в песочнице не имеет возможности отправлять сетевые запросы, так что же мне делать? Может быть отправлен только через сетевые процессы. Тогда это включает межпроцессное взаимодействие (IPC, Inter Process Communication). Далее давайте посмотрим, как осуществляется межпроцессное взаимодействие в хроме.Последовательность вызова в исходном коде хрома выглядит следующим образом:

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

В общем, используйтеUnix Domain SocketSockets, высокопроизводительная библиотека параллелизма сети, управляемая событиями.libeventПроцесс IPC, который завершает процесс.

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

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

Далее поговорим о нескольких решениях междоменных проблем.

CORS

CORS на самом деле является стандартом W3C, полное название跨域资源共享. Для этого требуется совместная поддержка браузера и сервера, в частности, не-IE и IE10 и выше поддерживают CORS, и сервер должен прикрепить определенный заголовок ответа, который будет разобран позже. Однако, прежде чем мы сможем понять принцип CORS, нам нужно понять две концепции:простой запроса такжене простой запрос.

Браузер классифицирует запрос в соответствии с методом запроса и конкретными полями заголовка запроса. В частности, правила следующие. Те, которые соответствуют следующим условиям, относятся кпростой запрос:

  • Метод запроса: GET, POST или HEAD.
  • Диапазон значений заголовка запроса: Accept, Accept-Language, Content-Language, Content-Type (ограничено тремя значениямиapplication/x-www-form-urlencoded,multipart/form-data,text/plain)

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

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

Что делает браузер перед отправкой запроса?

Он автоматически добавитOriginПоле для указания, откуда пришел запрос.服务器拿到请求之后,在回应时对应地添加Access-Control-Allow-Originполе, еслиOriginЗа рамками этого поля браузер перехватит ответ.

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

Access-Control-Allow-Credentials. Это поле имеет логическое значение, указывающее, разрешать ли отправку файлов cookie. Для междоменных запросов значение этого поля по умолчанию устанавливается браузером как false. Если вам нужно получить файл cookie браузера, вам нужно добавить этот заголовок ответа и установите его наtrue, а также должен быть установлен на переднем концеwithCredentialsАтрибуты:

let xhr = new XMLHttpRequest();
xhr.withCredentials = true;

Access-Control-Expose-Headers.这个字段是给 XMLHttpRequest 对象赋能,让它不仅可以拿到基本的 6 个响应头字段(包括Cache-Control,Content-Language,Content-Type,Expires,Last-Modifiedа такжеPragma), вы также можете получить объявление поляполя заголовка ответа.比如这样设置:

Access-Control-Expose-Headers: aaa

Затем в передней части вы можете пройтиXMLHttpRequest.getResponseHeader('aaa')получатьaaaЗначение этого поля.

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

Непростые запросы относительно отличаются двумя способами:предварительный запроса такжеполе ответа.

Возьмем в качестве примера метод PUT.

var url = 'http://xxx.com';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custom-Header', 'xxx');
xhr.send();

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

OPTIONS / HTTP/1.1
Origin: 当前地址
Host: xxx.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

Способ предварительной проверки запросаOPTIONSпри добавленииOriginисходный адрес иHostцелевой адрес, это просто. Также будут добавлены два ключевых поля:

  • Access-Control-Request-Method, в котором указано, какой метод HTTP используется для запросов CORS.
  • Access-Control-Request-Headers указывает, какие заголовки запросов будут добавлены в запросы CORS.

Это预检请求. Далееполе ответа, поле ответа также разделено на две части, одна часть предназначена дляпредварительный запросответ, частично дляCORS-запросответ на.

Ответ на предварительный запрос. Например, в следующем формате:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0

Некоторые из этих ключевыхполя заголовка ответа:

  • Access-Control-Allow-Origin: указывает источник, который может разрешить запрос, вы можете указать конкретное имя источника, вы также можете заполнить*Указывает, что разрешен любой запрос источника.
  • Access-Control-Allow-Methods: указывает список разрешенных методов запроса.
  • Access-Control-Allow-Credentials: введено в Simple Requests.
  • Access-Control-Tower-Headers: указывает поля заголовка запроса, которые могут быть отправлены
  • Access-Control-Max-Age: Срок действия предварительного запроса. В течение этого периода нет необходимости выдавать еще один предварительный запрос.

После возврата ответа на предварительный запрос, если запрос не соответствует условиям заголовка ответа, он запускается.XMLHttpRequestизonerrorметод, конечно, за реальнымCORS-запросЕго тоже не вышлют.

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

JSONP

несмотря на то чтоXMLHttpRequestОбъекты следуют той же политике происхождения, ноscriptМетка отличается, она может заполнить целевой адрес через src для отправки запроса GET, реализовать междоменный запрос и получить ответ. Это принцип JSONP, а затем мы инкапсулируем JSONP:

const jsonp = ({ url, params, callbackName }) => {
  const generateURL = () => {
    let dataStr = '';
    for(let key in params) {
      dataStr += `${key}=${params[key]}&`;
    }
    dataStr += `callback=${callbackName}`;
    return `${url}?${dataStr}`;
  };
  return new Promise((resolve, reject) => {
    // 初始化回调函数名称
    callbackName = callbackName || Math.random().toString.replace(',', ''); 
    // 创建 script 元素并加入到当前文档中
    let scriptEle = document.createElement('script');
    scriptEle.src = generateURL();
    document.body.appendChild(scriptEle);
    // 绑定到 window 上,为了后面调用
    window[callbackName] = (data) => {
      resolve(data);
      // script 执行完了,成为无用元素,需要清除
      document.body.removeChild(scriptEle);
    }
  });
}

Конечно, на стороне сервера также будут отзывчивые операции, в качестве примера возьмем экспресс:

let express = require('express')
let app = express()
app.get('/', function(req, res) {
  let { a, b, callback } = req.query
  console.log(a); // 1
  console.log(b); // 2
  // 注意哦,返回给script标签,浏览器直接把这部分字符串执行
  res.end(`${callback}('数据包')`);
})
app.listen(3000)

Внешний интерфейс просто вызывает это так:

jsonp({
  url: 'http://localhost:3000',
  params: { 
    a: 1,
    b: 2
  }
}).then(data => {
  // 拿到数据进行处理
  console.log(data); // 数据包
})

а такжеCORSПо сравнению с JSONP самое большое преимущество в том, что он имеет хорошую совместимость.Младшая версия IE не может использовать CORS, но можно использовать JSONP.Недостаток также очевиден.Метод запроса один и поддерживается только запрос GET.

Nginx

Nginx — это высокая производительность反向代理Сервер, который можно использовать для простого решения междоменных проблем.

какие? Обратный прокси? Я покажу тебе картинку, ты поймешь.

Форвард прокси помогает клиентамдоступСервер, к которому клиент не может получить доступ сам по себе, а затем возвращает результат клиенту.

Обратный прокси-сервер получает запрос клиента и перенаправляет запрос на другие серверы.Основной сценарий — поддерживать кластер серверов.Балансировка нагрузки, другими словами, обратный прокси помогаетдругие серверыПолучите запрос, затем выберите соответствующий сервер и перенаправьте запрос на него.

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

Хорошо, как Nginx решать кросс-домен?

Например, доменное имя клиента теперьclient.com, доменное имя сервераserver.com, клиент отправляет на сервер Ajax-запрос, естественно, он будет кроссдоменным, тогда пусть в это время появится Nginx, через следующую конфигурацию:

server {
  listen  80;
  server_name  client.com;
  location /api {
    proxy_pass server.com;
  }
}

Nginx эквивалентен трамплину, и доменное имя этого трамплина тожеclient.com, пусть клиент сначала получит доступclient.com/api, что само собой не является междоменным, то сервер Nginx выступает в роли обратного прокси, перенаправляя запрос наserver.com, когда ответ возвращается, ответ отправляется клиенту, который завершает весь процесс междоменного запроса.

На самом деле есть несколько менее распространенных способов, понятных каждому, напримерpostMessage,КонечноWebSocketТоже способ, но он уже не из разряда HTTP.Другие приемы и приемы не рекомендуется всем заучивать наизусть.С одной стороны, он никогда не используется, да и название трудно запомнить. с другой стороны, если он будет временно запоминаться, интервьюер также не даст вам дополнительных баллов, потому что видно, что это спина. Конечно, отсутствие запоминания не означает, что вы потеряете баллы.Если вы понимаете принцип междоменного доступа и три основных междоменных метода, описанных выше, и можете выдержать дальнейшую проверку, это заставит окружающих почувствовать, что вы надежный человек.

015: Каков процесс рукопожатия TLS1.2?

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

в результате этогоHTTPS, на самом деле это не новый протокол, а добавляет слой протокола SSL/TLS под HTTP.Проще говоря,HTTPS = HTTP + SSL/TLS.

Так что же такое SSL/TLS?

SSL означает Secure Sockets Layer, который находится на сеансовом уровне (уровень 5) в семиуровневой модели OSI. Раньше у SSL было три основные версии, и он был стандартизирован, когда он был разработан до третьей основной версии, которая стала TLS (Transport Layer Security) и, если быть точным, считалась версией TLS1.0.TLS1.0 = SSL3.1.

Текущая основная версия — TLS/1.2.Предыдущие версии TLS1.0 и TLS1.1 считаются небезопасными и будут полностью удалены в ближайшем будущем. Поэтому далее мы в основном обсуждаем TLS1.2.Конечно, в 2018 году был запущен улучшенный TLS1.3, который значительно оптимизировал процесс рукопожатия TLS.Об этом мы поговорим в следующем разделе.

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

Традиционное рукопожатие RSA

Давайте сначала поговорим о традиционном рукопожатии TLS, которое часто можно увидеть в Интернете. Я уже писал нечто подобное,(Традиционная версия RSA) HTTPS Зачем делать передачу данных более безопасной, который также вводит对称加密а также非对称加密Понятие , я предлагаю вам прочитать, и я не буду повторяться. Он называется версией RSA, потому что он шифрует и расшифровываетpre_randomПри использовании алгоритма RSA.

Процесс рукопожатия TLS 1.2

Теперь давайте поговорим о подходе, сделанном основной версией TLS 1.2.

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

step 1: Client Hello

Сначала браузер отправляет client_random, версию TLS, список наборов шифров.

Что такое client_random? Параметр, используемый для окончательного секрета.

Что такое список наборов шифров? Например, список наборов шифров обычно выглядит так:

TLS_ECDHE_WITH_AES_128_GCM_SHA256

смыслTLSВо время рукопожатия используйтеECDHEГенерация алгоритмаpre_random(Этот номер будет введен позже), 128-битныйAESАлгоритм используется для симметричного шифрования, а основной используется в процессе симметричного шифрования.GCMРежим группировки, потому что очень важным вопросом в симметричном шифровании является способ группировки. Последний из них — это алгоритм хэш-дайджеста, использующийSHA256алгоритм.

Стоит пояснить алгоритм хеш-дайджеста.Представьте себе сценарий, когда сервер сейчас отправляет сообщение клиенту, а клиент не знает, отправлено ли сообщение в это время сервером или сообщение подделано посредником. ? Теперь введите этот алгоритм хэш-дайджеста для передачи информации о сертификате сервера черезэтот алгоритмСоздайте сводку (которая может быть понята как比较短的字符串) ДлялоготипИдентификатор сервера, зашифрованный закрытым ключом,зашифрованная личностьа такжесобственный открытый ключпередано клиенту. Клиент получаетэтот открытый ключЧтобы расшифровать, сгенерируйте еще одну сводку. Два сводных сравнения, если одинаковые могут подтвердить личность сервера. Это так называемыйцифровой подписипринцип. Среди них, кроме алгоритма хеширования, самым важным процессом являетсяШифрование с закрытым ключом, дешифрование с открытым ключом.

step 2: Server Hello

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

server_randomтакже последнийsecretНетрудно понять параметр версии TLS, набор шифров, который необходимо использовать, и его собственный сертификат. остальныеserver_paramsДля чего это?

Давайте сначала заложим основу, теперь вам просто нужно знать,server_randomдошел до клиента.

Шаг 3: Клиент проверяет сертификат и создает секрет

Клиент проверяет с сервера证书а также签名Пройти или нет, пройти, если проходит проверкаclient_paramsЭтот параметр передается серверу.

Затем клиент проходитECDHEалгоритм вычисляетpre_random, который передается двумя параметрами:server_paramsа такжеclient_params.现在你应该清楚这个两个参数的作用了吧,由于ECDHEна основе椭圆曲线离散对数, эти два параметра также называются椭圆曲线的公钥.

У клиента сейчас естьclient_random,server_randomа такжеpre_random, а затем передать эти три числа через функцию псевдослучайных чисел, чтобы вычислить окончательныйsecret.

Шаг 4: Сервер генерирует секрет

Клиент просто не прошелclient_paramsТы здесь?

Теперь сервер начинает использоватьECDHEГенерация алгоритмаpre_random, затем используйте ту же функцию псевдослучайных чисел, что и клиент, чтобы сгенерировать окончательныйsecret.

Меры предосторожности

Процесс TLS в основном завершен, но следует отметить два момента.

Первый, на самом деле рукопожатие TLS являетсяДвусторонняя аутентификацияКак видно из шага 1, у клиента есть возможность проверить подлинность сервера.Может ли сервер проверить личность клиента?

Конечно, это возможно. В частности, вstep3клиент передаетclient_params, по сути, отправьте проверочное сообщение на сервер и позвольте серверу пройти тот же процесс проверки (хеш-дайджест + шифрование с закрытым ключом + расшифровка с открытым ключом), чтобы подтвердить личность клиента.

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

Это заключительное сообщение состоит из двух частей, одна частьChange Cipher Spec, что означает, что зашифрованная передача выполняется позже, а другаяFinishedсообщение, которое делается на все ранее отправленные данныеРезюме, зашифруйте дайджест и позвольте другой стороне проверить его.

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

Разница между процессом рукопожатия RSA и ECDHE

  1. Рукопожатие ECDHE, которое является основным рукопожатием TLS1.2, используетECDHEвыполнитьpre_randomШифрование и дешифрование, нет RSA.

  2. Используйте ECDHE, есть функция, с помощью которой клиент может заранее заполнить завершающее сообщение.抢跑, отправлять HTTP-сообщение напрямую, сохраняя RTT, вам не нужно ждать, пока окончательное сообщение прибудет на сервер, а затем ждать, пока сервер вернет окончательное сообщение самому себе, и начать отправку запроса напрямую. это также называетсяTLS False Start.

016: Какие улучшения внесены в TLS 1.3?

Хотя TLS 1.2 существует уже более 10 лет и прошел бесчисленное количество тестов, колесо истории всегда движется вперед.Чтобы получить более надежную защиту и лучшую производительность,2018年TLS1.3 был запущен дляTLS1.2Внесен ряд улучшений, которые в основном разделены на следующие части:Повышенная безопасность,Повысить производительность.

Повышенная безопасность

В TLS1.3 многие алгоритмы шифрования были упразднены, и в итоге осталось только пять наборов шифров:

  • TLS_AES_128_GCM_SHA256
  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_GCM_SHA256
  • TLS_AES_128_GCM_8_SHA256

Можно видеть, что последний оставшийся алгоритм симметричного шифрования толькоAESа такжеCHACHA20, в предыдущем мейнстриме тоже будут эти два. Режим группировки тоже оставленGCMа такжеPOLY1305, остается только алгоритм хэш-дайджестаSHA256а такжеSHA384.

Тогда вы можете спросить, прежде чемRSAКак исчез такой важный алгоритм асимметричного шифрования?

Я думаю, что есть две причины:

Первый, обнаружен в 2015 г.FREAKАтака, то есть кто-то обнаружил уязвимость RSA и может ее взломать.

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

Почему? Вернемся к процессу рукопожатия RSA, после того как клиент получит сертификат сервера, он извлечет открытый ключ сервера, а затем сгенерируетpre_randomиспользовать вместеоткрытый ключЗашифровано на сервер, сервер проходитзакрытый ключрасшифровать, чтобы получить настоящийpre_random. Когда посредник получает приватный ключ сервера и перехватывает все предыдущие сообщения, он может его получитьpre_random,server_randomа такжеclient_randomИ генерировать в соответствии с соответствующей функцией случайных чиселsecret, то есть получается окончательный сеансовый ключ TLS, и таким образом можно взломать каждое историческое сообщение.

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

RSAАлгоритм не имеет прямой безопасности, иECDHEДа, так его полностью заменили в TLS1.3RSA.

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

Улучшения рукопожатия

Процесс выглядит следующим образом:

Общий метод похож на TLS1.2, но по сравнению с TLS 1.2 на один RTT меньше, и серверу не нужно ждать, пока другая сторона проверит сертификат, прежде чем его получить.client_params, но может быть получен непосредственно при первом рукопожатии, и рассчитан сразу после его полученияsecret, экономя ненужное время ожидания раньше. В то же время это также означает, что клиенту нужно передать больше информации во время первого рукопожатия, которое передается за один раз.

Это рукопожатие TLS 1.3 также называется1-RTT рукопожатие. Но на самом деле это1-RTTВ режиме рукопожатия все еще есть оптимизированное пространство, и давайте введем эти методы оптимизации один за другим.

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

Существует два способа повторного использования сеанса:Session IDа такжеSession Ticket.

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

Однако у этого метода есть и недостаток: при большом количестве клиентов нагрузка на сервер очень велика.

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

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

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

PSK

просто сказал1-RTTВ случае оптимизации, может ли он быть оптимизирован для0-RTTШерстяная ткань?

Ответ положительный. Практика на самом деле очень проста, отправкаSession TicketПри этом привести данные приложения, не дожидаясь подтверждения сервера, этот метод называетсяPre-Shared Key, то есть PSK.

Хотя этот метод удобен, он также приносит проблемы с безопасностью. перехват человека посерединеPSKДанные повторно отправляются на сервер, аналогично первому рукопожатию TCP, несущему данные, что увеличивает риск атаки на сервер.

Суммировать

TLS1.3 отменяет большое количество алгоритмов на основе TLS1.2 и повышает безопасность. В то же время использование мультиплексирования сеансов экономит время повторного ключа, что достигается за счет использования PSK.0-RTTсоединять.

017: Какие улучшения в HTTP/2?

Поскольку HTTPS уже очень хорош в плане безопасности, улучшения HTTP сосредоточены на производительности. Для HTTP/2 улучшение производительности в основном заключается в двух моментах:

  • сжатие заголовка
  • мультиплексирование

Конечно, есть и некоторые подрывные функциональные реализации:

  • Установить приоритет запроса
  • пуш сервера

Эти основные улучшения также предназначены для решения проблем с самим HTTP. Далее давайте посмотрим, какие проблемы решает HTTP/2 и как их решить.

сжатие заголовка

В эпоху HTTP/1.1 и ранеетело запросаКак правило, будет выполняться процесс кодирования со сжатием ответа посредствомContent-EncodingПоле заголовка указать, а вы не думали о сжатии самого поля заголовка? Когда поля запроса очень сложные, особенно для GET-запросов, сообщение запроса почти полностью состоит из заголовков запроса.В настоящее время еще много возможностей для оптимизации. HTTP/2 также использует соответствующий алгоритм сжатия, HPACK, для поля заголовка, чтобы сжать заголовок запроса.

Алгоритм HPACK предназначен для HTTP/2 и имеет две основные особенности:

  • Первый — установить хеш-таблицу между сервером и клиентом, и хранить поля, используемые в этой таблице, Затем при передаче появившихся ранее значений нужно только поставитьпоказатель(Например, 0, 1, 2,...) могут быть переданы другой стороне, и другая сторона может получить таблицу поиска индекса. этобиографияМожно сказать, что поля заголовка запроса значительно упрощены и используются повторно.

В HTTP/2 концепция стартовой строки упразднена, а метод запроса, URI и код состояния в стартовой строке преобразуются в поля заголовков, но эти поля имеют префикс «:», чтобы отличить их от других заголовков запроса. . . .

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

мультиплексирование

Блокировка заголовка строки HTTP

Ранее мы обсуждали проблему блокировки заголовка строки HTTP, основная причина которой заключается в том, что HTTP основан на请求-响应модели, в том же длинном TCP-соединении предыдущий запрос не отвечает, а последний запрос будет заблокирован.

Позже мы обсудим использованиеодновременные соединенияа такжеШардинг доменаспособ решить эту проблему, но на самом деле это не решает проблему с уровня самого HTTP, он просто увеличивает TCP-соединение и распределяет риск. И у этого есть недостатки, несколько TCP-соединений будут конкурироватьограниченная пропускная способность, чтобы запросы с действительно высоким приоритетом не могли обрабатываться первыми.

И HTTP/2 решает это из самого протокола HTTP.队头阻塞вопрос. Заметьте, это не означаетTCP队头阻塞, ноHTTP队头阻塞, это не одно и то же. Блокировка заголовка TCP数据包уровень, единица数据包, если предыдущее сообщение не получено, сообщение, полученное позже, не будет загружено в HTTP, а заголовок очереди HTTP будет заблокирован.HTTP 请求-响应На уровне, если предыдущий запрос не обработан, последующий запрос будет заблокирован. Оба находятся на разных уровнях.

Так как же HTTP/2 решает так называемую блокировку заголовка строки?

Бинарное кадрирование

Во-первых, HTTP/2 считает, что передача открытого текста слишком хлопотна для машины, а компьютеру неудобно анализировать, потому что в тексте будут неоднозначные символы, например, являются ли возврат каретки и перевод строки содержание или разделитель, который необходимо использовать внутренне.Переход к конечной машине для идентификации, эффективность относительно низкая. Таким образом, HTTP/2 просто заменяет все сообщения в двоичном формате и передает их все.01string, что облегчает разбор машины.

оказалосьHeaders + BodyФормат сообщения теперь разделен на двоичные кадры с использованиемРамка заголовковСохраните поле заголовка,Фрейм данныхСохранение данных тела запроса. После кадрирования сервер видит уже не полное сообщение HTTP-запроса, а набор неупорядоченных двоичных кадров. Между этими двоичными кадрами нет связи последовательности, поэтому нет ожидания в очереди и нет проблемы блокировки HTTP-заголовка строки.

Обе стороны связи могут отправлять друг другу бинарные кадры.двунаправленная последовательность передачиака(Поток). Для HTTP/2Для передачи нескольких кадров данных по TCP-соединению этомультиплексированиеКонцепция чего-либо.

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

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

пуш сервера

Также стоит упомянуть о HTTP/2-сервере push (Server Push). В HTTP/2 сервер больше не является полностью пассивным для получения запросов и ответа на запросы. Он также может создавать новый поток для отправки сообщений клиенту. Когда установлено TCP-соединение, например, когда браузер запрашивает HTML-файл, сервер может на основе возврата HTML, другие файлы ресурсов, на которые есть ссылки в HTML, возвращаются клиенту вместе, чтобы сократить время ожидания клиента.

Суммировать

Конечно, с таким количеством новых функций, добавленных в HTTP/2, нужно ли заново изучать синтаксис HTTP? Нет, HTTP/2 полностью совместим с предыдущим синтаксисом и семантикой HTTP, такими какЗаголовки запросов, URI, коды состояния, поля заголовковНичего не изменилось, не переживайте. В то же время, с точки зрения безопасности, HTTP также поддерживает TLS, и теперь основные браузеры публично поддерживают только зашифрованный HTTP/2, поэтому HTTP/2, который вы видите, теперь в основном работает на TLS. Наконец, поместите многоуровневую диаграмму для справки:

018: Как устроены бинарные фреймы в HTTP/2?

каркасная конструкция

Структура кадра, передаваемого в HTTP/2, показана на следующем рисунке:

Каждый кадр делится на帧头а также帧体. Во-первых, длина кадра три байта, эта длина представляет собой帧体длина.

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

Следующий байтрамка с логотипом, всего 8 флаговых битов, обычно используютсяEND_HEADERSУказывает конец данных заголовка,END_STREAMУказывает на окончание однонаправленной передачи данных.

Последние 4 байтаStream ID, то есть,流标识符, с его помощью получатель может выбирать кадры с одинаковым идентификатором из неупорядоченных двоичных кадров и последовательно собирать их в сообщения запроса/ответа.

Государственное изменение потока

Как видно спереди, в HTTP/2 так называемый, который на самом деле является бинарным фреймомдвунаправленная последовательность передачи. Так как же изменяется состояние потока во время запросов и ответов HTTP/2?

Фактически, HTTP/2 также опирается на идею изменения состояния TCP и реализует конкретное изменение состояния в соответствии с флаговым битом кадра. Здесь мы используем обычный请求-响应Процесс в качестве примера для иллюстрации:

Первоначально обои простые состояние, когда клиент отправляетHeaders帧После этого приступайте к назначениюStream ID, клиентОткрыть, после того как сервер получиттакже открыты, оба концаПосле того, как оба открыты, кадры данных и кадры управления могут быть переданы друг другу.

Когда клиент хочет закрыть, отправить на серверEND_STREAMрамка, введите半关闭状态, В это время клиент может только получать данные, но не может отправлять данные.

Сервер получает этоEND_STREAMтакже введите после кадра半关闭状态, но в это время сервер может только отправлять данные, но не может получать данные. Затем сервер также отправляет клиентуEND_STREAMкадр, указывающий, что передача данных завершена, и обе стороны входят关闭状态.

Если вы хотите открыть новый в следующий раз, идентификатор потока должен автоматически увеличиваться до тех пор, пока не будет достигнут верхний предел.По достижении верхнего предела открывается новое TCP-соединение, и отсчет начинается с самого начала. Поскольку поле идентификатора потока имеет длину 4 байта, а старший бит зарезервирован, диапазон составляет от 0 до 2 в 31-й степени, около 2,1 миллиарда.

свойства потока

Только что говорили о процессе изменения состояния потока, вот, кстати, краткое изложениеХарактеристики трансмиссии:

  • параллелизм. В отличие от HTTP/1, несколько кадров могут быть отправлены одновременно по соединению HTTP/2. Это также достигаетсямультиплексОснова для повторного использования.
  • Самовозрастающий. Идентификаторы потоков не могут использоваться повторно, а увеличиваются последовательно, и при достижении верхнего предела новое TCP-соединение открывается с самого начала.
  • Двунаправленность. И клиент, и сервер могут создавать потоки, не мешая друг другу, и обе стороны могут действовать как发送方или接收方.
  • Можно установить приоритет. Вы можете установить приоритет фрейма данных, позволить серверу сначала обрабатывать важные ресурсы и оптимизировать взаимодействие с пользователем.

Вышеприведенное является введением в двоичный фрейм в HTTP/2, надеюсь, оно вас вдохновит.

наконец

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

Ссылаться на:

«Подробное объяснение веб-протокола и захват пакетов — Тао Хуэй»

"Перспективный HTTP-протокол" - хроно

Источник исходного кода хрома IPC

Необходимые знания Nginx для фронтенд-разработчиков - conardli