Простою мовою про HTTP. Параметри запиту: Як параметри надсилаються до HTTP-запиту POST? xx: Інформаційні повідомлення

HTTP – це протокол передачі гіпертексту між розподіленими системами. Власне, http є фундаментальним елементом сучасного Web-а. Як поважають себе веб-розробники, ми повинні знати про нього якомога більше.

Погляньмо на цей протокол через призму нашої професії. У першій частині пройдемося основами, подивимося на запити/відповіді. У наступній статті розберемо більш детальні фішки, такі як кешування, обробка підключення та автентифікація.

Також у цій статті я буду в основному посилатися на стандарт RFC 2616: Hypertext Transfer Protocol - HTTP/1.1.

Основи HTTP

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

В основному для спілкування використовується TCP/IP, але це не єдиний можливий варіант. За замовчуванням TCP/IP використовує порт 80, але можна заюзати й інші.

Спілкування між хостом та клієнтом відбувається у два етапи: запит та відповідь. Клієнт формує HTTP запит, у відповідь який сервер дає відповідь (повідомлення). Трохи пізніше ми детальніше розглянемо цю схему роботи.

Поточна версія протоколу HTTP - 1.1, де було введено деякі нові фішки. На мою думку, найважливіші з них це: підтримка постійно відкритого з'єднання, новий механізм передачі даних chunked transfer encoding, нові заголовки для кешування. Щось із цього ми розглянемо у другій частині цієї статті.

URL

Серцевиною веб-спілкування є запит, що надсилається через Єдиний покажчик ресурсів (URL). Я впевнений, що ви вже знаєте, що таке URL-адреса, проте для повноти картини, вирішив все-таки сказати пару слів. Структура URL дуже проста і складається з таких компонентів:

Протокол може бути http для звичайних з'єднань, так і https для безпечнішого обміну даними. Порт за замовчуванням - 80. Далі слідує шлях до ресурсу на сервері та ланцюжок параметрів.

Методи

За допомогою URL ми визначаємо точну назву хоста, з яким хочемо спілкуватися, проте яку дію нам потрібно вчинити, можна повідомити тільки за допомогою HTTP методу. Звичайно, існує кілька видів дій, які ми можемо зробити. У HTTP реалізовані найпотрібніші, які підходять під потреби більшості додатків.

Існуючі методи:

GET: отримати доступ до наявного ресурсу В URL перерахована вся необхідна інформація, щоб сервер зміг знайти і повернути як відповідь шуканий ресурс.

POST: використовується для створення нового ресурсу POST запит зазвичай містить у собі всю необхідну інформацію для створення нового ресурсу.

PUT: оновлення поточного ресурсу. PUT запит містить оновлювані дані.

DELETE: Видалення існуючого ресурсу.

Дані методи найпопулярніші і найчастіше використовуються різними інструментами та фреймворками. У деяких випадках PUT і DELETE запити надсилаються за допомогою відправки POST, у змісті якого зазначено дію, яку потрібно вчинити з ресурсом: створити, оновити або видалити.

Також HTTP підтримує інші методи:

HEAD: аналогічний GET. Різниця в тому, що при цьому виді запиту не передається повідомлення. Сервер отримує лише заголовки. Використовується, наприклад, щоб визначити, чи було змінено ресурс.

TRACE: під час передачі запит проходить через безліч точок доступу та проксі серверів, кожен із яких вносить свою інформацію: IP, DNS. За допомогою даного методу можна побачити всю проміжну інформацію.

OPTIONS: використовується для визначення можливостей сервера, його параметрів та конфігурації для конкретного ресурсу.

Коди стану

У відповідь на запит від клієнта сервер відправляє відповідь, яка містить, у тому числі, і код стану. Цей код несе в собі особливий сенс для того, щоб клієнт міг чіткіше зрозуміти, як інтерпретувати відповідь:

1xx: Інформаційні повідомлення

Набір цих кодів було введено у HTTP/1.1. Сервер може надіслати запит виду: Expect: 100-continue, що означає, що клієнт ще відправляє частину запиту. Клієнти, що працюють з HTTP/1.0, ігнорують дані заголовки.

2xx: Повідомлення про успіх

Якщо клієнт отримав код із серії 2xx, то запит пішов успішно. Найпоширеніший варіант – це 200 OK. При запиті GET, сервер відправляє відповідь в тілі повідомлення. Також існують інші можливі відповіді:

  • 202 Accepted: запит прийнято, але може не містити ресурс у відповіді. Це корисно для асинхронних запитів на стороні сервера. Сервер визначає, надіслати ресурс чи ні.
  • 204 No Content: у тілі відповіді немає повідомлення.
  • 205 Reset Content: вказівка ​​серверу про скидання представлення документа
  • 206 Partial Content: відповідь містить лише частину контенту. У додаткових заголовках визначається загальна довжина контенту та інфа.

3xx: Перенаправлення

Своєрідне повідомлення клієнту про необхідність вчинити ще одну дію. Найпоширеніший варіант застосування: перенаправити клієнт на іншу адресу.

  • 301 Moved Permanently: ресурс тепер можна знайти за іншою URL-адресою.
  • 303 See Other: ресурс тимчасово можна знайти за іншою URL-адресою. Заголовок Location містить тимчасову URL-адресу.
  • 304 Відмінно: сервер визначає, що ресурс не змінено і клієнту потрібно задіяти закешированную версію відповіді. Для перевірки ідентичності інформації використовується ETag (хеш Сутності – Enttity Tag);

4xx: Клієнтські помилки

Цей клас повідомлень використовується сервером, якщо він вирішив, що запит було надіслано з помилкою. Найбільш поширений код: 404 Not Found. Це означає, що ресурс не знайдено на сервері. Інші можливі коди:

  • 400 Bad Request: питання було сформовано невірно
  • 401 Unauthorized: для запиту потрібна аутентифікація. Інформація передається через заголовок Authorization.
  • 403 Forbidden: сервер не відкрив доступ до ресурсу
  • 405 Method Not Allowed: неправильний метод HTTP був задіяний для того, щоб отримати доступ до ресурсу.
  • 409 Conflict: сервер неспроможна остаточно обробити запит, т.к. намагається змінити новішу версію ресурсу. Це часто відбувається при запитах PUT.

5xx: Помилки сервера

Ряд кодів, що використовуються визначення помилки сервера під час обробки запиту. Найпоширеніший: 500 Internal Server Error. Інші варіанти:

  • 501 Not Implemented: сервер не підтримує потрібну функціональність.
  • 503 Service Unavailable: це може статися, якщо на сервері сталася помилка або він перевантажений. Зазвичай у цьому випадку сервер не відповідає, а час, даний на відповідь, спливає.

Формати повідомлень запиту/відповіді

На наступному зображенні ви можете побачити схематично оформлений процес надсилання запиту клієнтом, обробка та надсилання відповіді сервером.

Давайте подивимося на структуру повідомлення, що передається через HTTP:

Message = *() CRLF [ ] = Request-Line | Status-Line = Field-Name ":" Field-Value

Між заголовком і тілом повідомлення повинен обов'язково бути порожній рядок. Заголовків може бути декілька:

Тіло відповіді може містити повну інформацію або її частину, якщо активовано відповідну можливість (Transfer-Encoding: chunked). HTTP/1.1 також підтримує заголовок Transfer-Encoding.

Загальні заголовки

Ось кілька видів заголовків, які використовуються як у запитах, так і у відповідях:

General-header = Cache-Control | Connection | Date | Pragma | Trailer | Transfer-Encoding | Upgrade | Via | Warning

Щось ми вже розглянули в цій статті, щось детальніше торкнемося в другій частині.

Заголовок via використовується у запиті типу TRACE, та оновлюється всіма проксі-серверами.

Заголовок Pragma використовується для перерахування власних заголовків. Наприклад, Pragma: no-cache - це те саме, що Cache-Control: no-cache. Докладніше про це поговоримо у другій частині.

Заголовок Date використовується для зберігання дати та часу запиту/відповіді.

Заголовок Upgrade використовується для зміни протоколу.

Transfer-Encoding призначається поділу відповіді кілька фрагментів з допомогою Transfer-Encoding: chunked. Це новація версії HTTP/1.1.

Заголовки сутностей

У заголовках сутностей передається мета-інформація контенту:

Entity-header = Allow | Content-Encoding | Content-Language | Content-Length | Content-Location | Content-MD5 | Content-Range | Content-Type | Expires | Last-Modified

Всі заголовки з префіксом Content-надають інформацію про структуру, кодування та розмір тіла повідомлення.

Заголовок Expires містить час і дату закінчення сутності. Значення “never expires” означає час + 1 код із поточного моменту. Last-Modified містить час та дату останньої зміни сутності.

За допомогою даних заголовків можна задати потрібну для ваших завдань інформацію.

Формат запиту

Запит виглядає приблизно так:

Request-Line = Метод SP URI SP HTTP-Version CRLF Метод = "OPTIONS" | "HEAD" | "GET" | "POST" | "PUT" | "DELETE" | "TRACE"

SP – це роздільник між токенами. Версія HTTP вказується у HTTP-Version. Реальний запит має такий вигляд:

GET /articles/http-basics HTTP/1.1 Host: www.articles.com Connection: keep-alive Cache-Control: no-cache Pragma: no-cache Accept: text/html,application/xhtml+xml,application/xml; q=0.9,*/*;q=0.8

Список можливих заголовків запиту:

Request-header = Accept | Accept-Charset | Accept-Encoding | Accept-Language | Authorization | Expect | від | Host | If-Match | If-Modified-Since | If-None-Match | If-Range | If-Unmodified-Since | Max-Forwards | Proxy-Authorization | Range | Referer | TE | User-Agent

У заголовку Accept визначається типи, мова, кодування символів, що підтримуються mime. Заголовки From, Host, Referer та User-Agent містять інформацію про клієнта. Префікси If призначені для створення умов. Якщо умова не пройшла, виникне помилка 304 Not Modified.

Формат відповіді

Формат відповіді відрізняється лише статусом та низкою заголовків. Статус виглядає так:

Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

  • HTTP версія
  • Код статусу
  • Повідомлення статусу, зрозуміле для людини

Звичайний статус виглядає приблизно так:

HTTP/1.1 200 OK

Заголовки відповіді можуть бути такими:

Response-header = Accept-Ranges | Age | ETag | Location | Proxy-Authenticate | Retry-After | Server | Vary | WWW-Authenticate

  • Age час у секундах, коли повідомлення було створено на сервері.
  • ETag MD5 сутності для перевірки змін та модифікацій відповіді.
  • Location використовується для перенаправлення та містить нову URL-адресу.
  • Server визначає сервер, де було сформовано відповідь.

Думаю, на сьогодні теорії достатньо. Тепер давайте поглянемо на інструменти, якими ми можемо скористатися для моніторингу HTTP повідомлень.

Інструменти для визначення HTTP трафіку

Існує безліч інструментів для моніторингу HTTP трафіку. Ось кілька із них:

Найчастіше використовується - це Chrome Developers Tools:

Якщо говорити про відладчика, можна скористатися Fiddler:

Для відстеження HTTP трафіку вам знадобиться curl, tcpdump та tshark.

Бібліотеки для роботи з HTTP - jQuery AJAX

Оскільки jQuery дуже популярний, він також має інструментарій для обробки HTTP відповідей при AJAX запитах. Інформацію про jQuery.ajax(settings) можна знайти на офіційному сайті.

Передаючи об'єкт налаштувань (settings), а також скориставшись функцією зворотного виклику beforeSend, ми можемо задати заголовки запиту за допомогою методу setRequestHeader().

$.ajax(( url: "http://www.articles.com/latest", тип: "GET", beforeSend: function (jqXHR) ( jqXHR.setRequestHeader("Accepts-Language", "en-US,en "); )));

Якщо хочете обробити статус запиту, це можна зробити так:

$.ajax(( statusCode: ( 404: function() ( alert("page not found"); ) ) )));

Підсумок

Ось такий він, тур по основах протоколу HTTP. У другій частині буде ще більше цікавих фактів та прикладів.

Чи є ви програмістом чи ні, ви бачили його всюди в Інтернеті. На даний момент в адресному рядку браузера відображається щось, що починається з http://. Навіть ваш перший скрипт Hello World надіслав HTTP-header без вашого розуміння. У цій статті ми збираємося дізнатися про основи HTTP-заголовків та про те, як їх можна використовувати у наших веб-додатках.

Що таке HTTP Headers?

HTTP означає "Hypertext Transfer Protocol" (Протокол передачі гіпертексту). Всесвітнє павутиння використовує цей протокол. Він був створений на початку 90-х років. Майже все, що ви бачите у вашому браузері, передається на ваш комп'ютер через HTTP. Наприклад, коли ви відкрили сторінку цієї статті, ваш браузер надіслав більше 40 запитів HTTP і отримав HTTP-відповіді для кожного з них.

Заголовки HTTP є основною частиною цих HTTP-запитів і відповідей, і вони несуть інформацію про браузер клієнта, запитану сторінку, сервер і багато іншого.

приклад

Коли ви вводите URL-адресу в адресному рядку, ваш браузер відправляє HTTP-запит, і він може виглядати так:

GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1 Host: net.tutsplus.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9. 1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729) 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 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120 Pragma: no-cache Cache-Control: no-cache

Перший рядок - це "Request Line", який містить деяку базову інформацію на запит. Інші - HTTP заголовки.

Після цього запиту ваш браузер отримує відповідь HTTP, яка може виглядати так:

HTTP/1.x 200 OK Transfer-Encoding: chunked Дата: Sat, 28 Nov 2009 04:36:25 GMT Server: LiteSpeed ​​Connection: close X-Powered-By: W3 Total Cache/0.8 Pragma: public Expires: Sat, 28 Nov 2009 05:36:25 GMT Etag: "pub1259380237;gz" Cache-Control: max-age=3600, public Content-Type: text/html; charset=UTF-8 Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT X-Pingback: http://net.tutsplus.com/xmlrpc.php Content-Encoding: gzip Vary: Accept-Encoding, Cookie, User-Agent Top 20+ MySQL Best Practices - Nettuts+

Перший рядок - це "Рядок стану", за яким слідують "HTTP-заголовки", до порожнього рядка. Після цього починається «вміст» (у разі - HTML висновок).

Коли ви дивитеся на вихідний код веб-сторінки у своєму браузері, ви бачите лише частину HTML, а не заголовки HTTP, хоча вони фактично були передані разом.

Ці HTTP-запити також надсилаються та приймаються для інших речей, таких як зображення, CSS-файли, файли JavaScript тощо. Саме тому я сказав раніше, що ваш браузер відправив не менше 40 або більше HTTP-запитів, оскільки ви завантажили тільки цю сторінку статті.

Тепер давайте розглянемо структуру докладніше.

Як побачити HTTP Headers

Для аналізу HTTP-заголовків я використовую такі розширення Firefox:

Заголовки HTTP у запитах HTTP

Тепер ми розглянемо деякі з найпоширеніших HTTP headers, знайдених у HTTP requests.

Майже всі ці заголовки можна знайти в масиві $_SERVER у PHP. Ви також можете використовувати функцію getallheaders() для отримання всіх заголовків одночасно.

Host

HTTP-запит надсилається на певні IP-адреси. Але оскільки більшість серверів здатні розміщувати кілька сайтів під одним IP, вони повинні знати, яке доменне ім'я шукає браузер.

Host: net.tutsplus.com

Це в основному ім'я host, включаючи домен та піддомен.

У PHP його можна знайти як $_SERVER["HTTP_HOST"] або $_SERVER["SERVER_NAME"].

User-Agent

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)

Цей заголовок може містити декілька частин інформації, таких як:

  • Ім'я та версія браузера.
  • Назва та версія операційної системи.
  • Мова за замовчуванням.

Саме так веб-сайти можуть збирати певну загальну інформацію про свої системи surfers. Наприклад, вони можуть визначити, чи використовує surfer мобільний браузер і перенаправляє їх на мобільну версію свого веб-сайту, який краще працює з низькою роздільною здатністю.

PHP може бути виражений так: $_SERVER["HTTP_USER_AGENT"].

If (strstr($_SERVER["HTTP_USER_AGENT"],"MSIE 6")) ( echo "Please stop using IE6!"; )

Accept-Language

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

Цей заголовок відображає налаштування мови за промовчанням. Якщо сайт має різні мовні версії, він може перенаправити новий surfer на основі цих даних.

У PHP його можна знайти так: $_SERVER ["HTTP_ACCEPT_LANGUAGE"].

If (substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2) == "fr") ( header("Location: http://french.mydomain.com"); )

Accept-Encoding

Accept-Encoding: gzip, deflate

Більшість сучасних браузерів підтримують gzip та відправляють це у header. Потім веб-сервер може надіслати вихідний HTML-код у стислому форматі. Це дозволяє зменшити розмір до 80% для економії пропускної спроможності та часу.

У PHP його можна знайти так: $_SERVER ["HTTP_ACCEPT_ENCODING"]. Однак, коли ви використовуєте функцію зворотного виклику ob_gzhandler() , вона перевірятиме значення автоматично, тому вам це не потрібно.

// enables output buffering // and all output is compressed if the browser supports it ob_start("ob_gzhandler");

If-Modified-Since

Якщо веб-документ вже збережено в кеші в браузері і ви відвідуєте його знову, ваш браузер може перевірити, чи документ оновлено, надіславши наступне:

Якщо він не змінювався з цієї дати, сервер відправляє код відповіді "304 Not Modified", а вміст - ні, і браузер завантажує вміст із cache.

У PHP його можна знайти так: $_SERVER ["HTTP_IF_MODIFIED_SINCE"].

// assume $last_modify_time був останній вихід був updated // did the browser send If-Modified-Since header? if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) ( // if the browser cache matches the modify time if ($last_modify_time == strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"])) ( // send a 3 no content header("HTTP/1.1 304 Not Modified");

Існує також HTTP заголовок Etag, який можна використовувати для перевірки поточного кеша. Ми поговоримо про це найближчим часом.

Cookie

Як випливає з назви, це надсилає файли cookie, що зберігаються у вашому браузері для цього домену.

Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120; foo=bar

Це пари name=value, розділені крапками з комою. Cookies можуть також містити id сеансу.

У PHP окремі cookie-файли можуть бути доступні за допомогою масиву $_COOKIE. Ви можете безпосередньо звертатися до змінних сеансу, використовуючи масив $_SESSION, і якщо вам потрібен id сеансу, ви можете використовувати функцію session_id() замість cookie.

Echo $_COOKIE["foo"]; // output: bar echo $_COOKIE["PHPSESSID"]; // output: r2t5uvjq435r4q7ib3vtdjq120 session_start(); echo session_id(); // output: r2t5uvjq435r4q7ib3vtdjq120

Referer

Як випливає з назви, цей HTTP header містить url посилання.

Наприклад, якщо я зайшов на домашню сторінку Nettuts+ і натиснув посилання на статтю, цей header буде відправлено до мого браузера:

Referer: http://net.tutsplus.com/

У PHP його можна знайти як $_SERVER ["HTTP_REFERER"].

If (isset($_SERVER["HTTP_REFERER"])) ( $url_info = parse_url($_SERVER["HTTP_REFERER"]); // is the surfer coming from Google? if ($url_info["host"] == "www .google.com") ( parse_str($url_info["query"], $vars); : // http://www.google.com/search?source=ig&hl=en&rlz=&=&q=http+headers&aq=f&oq=&aqi=g-p1g9 // output will be: // You searched on Google for this keyword: http headers

Можливо, ви помітили, що слово "referrer" написано з помилкою, як "referr". На жаль, він перетворився на офіційну специфікацію HTTP так само і застряг.

Authorization

Authorization: Basic bXl1c2VyOm15cGFzcw==

Дані всередині header мають кодування base64. Наприклад, base64_decode ("bXl1c2VyOm15cGFzcw ==") поверне "myuser: mypass"

У PHP ці значення можна знайти як $_SERVER ["PHP_AUTH_USER"] та $_SERVER ["PHP_AUTH_PW"].

Докладніше про це буде, коли ми поговоримо про заголовок WWW-Authenticate.

Заголовки HTTP у відповідях HTTP

Тепер ми розглянемо деякі з найпоширеніших HTTP headers, знайдених у відповідях HTTP.

У PHP можна встановити заголовки відповіді, використовуючи функцію header() . PHP вже відправляє певні заголовки автоматично, для завантаження вмісту та налаштування файлів cookie та інше. Ви можете перевірити, чи були надіслані заголовки за допомогою функції headers_sent() .

Cache-Control

Визначення з w3.org: «Поле заголовка Cache-Control використовується для вказівки директив, які ПОВИННІ виконувати всі механізми кешування по ланцюжку запитів/відповідей». Ці "механізми кешування" включають шлюзи та проксі, які може використовувати ваш інтернет-провайдер.

Cache-Control: max-age=3600, public

"public" означає, що відповідь може бути кешована будь-ким. "max-age" вказує, скільки секунд дійсний кеш. Роздільна здатність кешування вашого веб-сайту може понизити навантаження на сервер і пропускну здатність, також збільшити час завантаження в браузері.

Кешування також можна запобігти за допомогою директиви "no-cache".

Cache-Control: no-cache

Content-Type

Цей header вказує на "mime-type" документа. Потім браузер визначає, як інтерпретувати вміст на основі цього. Наприклад, сторінка html (або PHP-скрипт з виходом html) може повертати це:

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

"text" - це тип, а "html" - підтип документа. Заголовок також може містити більше інформації, такої як Charset.

Для gif-зображення це може бути надіслано.

Content-Type: image/gif

Браузер може використовувати зовнішню програму або розширення браузера на основі mime-type. Наприклад, це призведе до завантаження Adobe Reader:

Content-Type: application/pdf

При завантаженні безпосередньо Apache може виявити mime-тип документа і відправити відповідний header. Крім того, більшість браузерів мають певний ступінь відмовостійкості та автовизначення типів mime, якщо заголовки вказані неправильно або відсутні.

Ви можете знайти список загальних типів mime.

У PHP можна використовувати функцію finfo_file() для визначення mime-типу файлу.

Content-Disposition

Цей header вказує браузеру відкрити вікно завантаження файлу замість того, щоб намагатися проаналізувати вміст. Приклад:

Content-Disposition: attachment; filename="download.zip"

Це змусить браузер зробити це:

Зверніть увагу, що відповідний заголовок Content-Type також має бути надісланий разом із цим:

Content-Type: application/zip Content-Disposition: attachment; filename="download.zip"

Content-Length

Коли контент передаватиметься браузеру, сервер може вказати його розмір (в байтах), використовуючи цей header.

Content-Length: 89123

Це особливо корисно для завантаження файлів. Саме так браузер може визначити перебіг завантаження.

Наприклад, ось сценарій-макет, який я написав, імітує повільне завантаження.

// it"s zip file header("Content-Type: application/zip"); // 1 million bytes (about 1megabyte) header("Content-Length: 1000000"); // load a download dialogue, and save it as download.zip header("Content-Disposition: attachment; filename="download.zip""); // 1000 times 1000 bytes of data for ($i = 0; $i< 1000; $i++) { echo str_repeat(".",1000); // sleep to slow down the download usleep(50000); }

Ось результат:

Тепер я збираюся закоментувати заголовок Content-Length

// it"s zip file header("Content-Type: application/zip"); // the browser won"t know the size // header("Content-Length: 1000000"); // load a download dialogue, and save it as download.zip header("Content-Disposition: attachment; filename="download.zip""); // 1000 times 1000 bytes of data for ($i = 0; $i< 1000; $i++) { echo str_repeat(".",1000); // sleep to slow down the download usleep(50000); }

Тепер результат такий:

Браузер може тільки сказати скільки байтів було завантажено, але він не знає загальну суму. Індикатор виконання не показує прогресу.

Etag

Це ще один header, який використовується для кешування. Це виглядає так:

Etag: "pub1259380237; gz"

Веб-сервер може надсилати цей header з кожним документом, який він обслуговує. Значення може ґрунтуватися на останній зміненій даті, розмірі файлу або навіть контрольній сумі файлу. Браузер потім зберігає це значення, оскільки він кешує документ. Наступного разу, коли браузер запитує той самий файл, він відправляє це в HTTP-запиті:

If-None-Match: "pub1259380237; gz"

Якщо значення Etag документа збігається з цим, сервер відправлятиме код 304 замість 200, і ніякого вмісту. Браузер завантажуватиме вміст із свого кеша.

Last-Modified

Як випливає з назви, цей header вказує дату останньої зміни документа у форматі GMT:

Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT $modify_time = filemtime($file); header("Last-Modified: ".

Це пропонує браузер інший спосіб для cache документа. Браузер може надіслати це в HTTP-запиті:

Ми вже говорили про це раніше у розділі "If-Modified-Since".

Location

Цей заголовок використовується для перенаправлення. Якщо код відповіді 301 або 302, сервер також має надіслати цей header. Наприклад, коли ви перейдете на сторінку http://www.nettuts.com, ваш браузер отримає наступне:

HTTP/1.x 301 Moved Permanently ... Location: http://net.tutsplus.com/ ...

У PHP ви можете перенаправити surfer так:

Header("Location: http://net.tutsplus.com/");

За замовчуванням це надішле 302 код відповіді. Якщо ви бажаєте замість 301 відправити:

Header("Location: http://net.tutsplus.com/", true, 301);

Set-Cookie

Коли веб-сайт хоче встановити або оновити файл cookie у вашому браузері, він використовуватиме цей header.

Set-Cookie: skin = noskin; path=/; domain=.amazon.com; expires=Sun, 29-Nov-2009 21:42:28 GMT Set-Cookie: session-id=120-7333518-8165026; path=/; domain=.amazon.com; expires=Sat Feb 27 08:00:00 2010 GMT

Кожен файл cookie надсилається як окремий header. Зауважте, що файли cookie, встановлені за допомогою JavaScript, не проходять через HTTP headers.

У PHP можна встановити cookie-файли, використовуючи функцію setcookie() , а PHP відправляє відповідні HTTP headers.

Setcookie("TestCookie", "foobar");

Що призводить до надсилання цього заголовка:

Set-Cookie: TestCookie=foobar

Якщо дата закінчення терміну дії не вказана, cookie видаляється, коли вікно браузера закрито.

WWW-Authenticate

Сайт може надіслати цей header для автентифікації користувача через HTTP. Коли браузер побачить цей header, він відкриє діалогове вікно входу до системи.

WWW-Authenticate: Basic realm="Restricted Area"

Що виглядатиме так:

запиту структура (8)

У запиті HTTP GETпараметри надсилаються як рядок запиту :

http://example.com/page ?parameter=value&also=another

У запиті HTTP POSTпараметри не надсилаються разом з URI.

Де значення? У заголовку запиту? У тілі запиту? На що це схоже?

Answers

Значення форм HTTP-POST-повідомлень надсилаються в тіло запиту в тому ж форматі, що і запит.

Для отримання додаткової інформації див. spec.

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

Запит POST може семантично виглядати так:

POST /?AuthId=YOURKEY&Action=WebServiceAction&Signature=rcLXfkPldrYm04 HTTP/1.1 Content-Type: text/tab-separated-values; charset=iso-8859-1 Content-Length: Host: webservices.domain.com Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: identity User-Agent: Mozilla/3.0 (компактний; Indy Library) name id John G12N

Цей підхід логічно поєднує QueryString і Body-Post з використанням одного Content-Type, який є «інструкцією з синтаксичного розбору» для веб-сервера.

Зверніть увагу: HTTP/1.1 загорнутав #32 (пробіл) зліва і з #10 (Line feed) праворуч.

Насамперед, давайте GET і POST

Отримати:Це HTTP запит за промовчанням, який робиться на сервері, і використовується для вилучення даних із сервера та рядка запиту, який з'являється після? в URI використовується для отримання унікального ресурсу.

це формат

GET /someweb.asp?data=value HTTP/1.0

тут data = value - передане значення рядка запиту.

POST:він використовується для безпечного відправлення даних на сервер, щоб все, що необхідно, це формат запиту POST

POST /somweb.aspHTTP/1.0 Host: localhost Content-Type: application/x-www-form-urlencoded //Ви можете надати будь-який формат, який ви знайдете Content-Length: 11 //it depends Name= somename

Чому POST над GET?

У GET значення, яке надсилається на сервери, зазвичай додається до базової URL-адреси в рядку запиту. Це дозволяє зламати ваші дані (це було проблемою в дні для Facebook, де були встановлені ваші облікові дані), тому POST, що використовується для відправлення даних на сервер, який використовував Request Body для відправлення ваших даних на сервер, який більш безпечний, оскільки він приховує ваші дані дані, і він отримує ваші дані з полів, обчислює їх довжину і додає їх у header для content-length і ніякі важливі дані безпосередньо не додаються до URL

тепер, коли ваш запит захищений, будь-які значення, що надсилаються на сервер, можуть бути відправлені в Request Body оскільки ім'я передбачає, що воно міститиме користувачів даних, які хотіли б відправити (і Він відправляється в URL Encoded форматі URL Encoded), а Request Headers зберігайте запит безпечним шляхом порівняння значень у Request Body з Request Headers

Ви можете використовувати мережний розділ Google Developer Tools, щоб дізнатися основну інформацію про те, як запити виконуються на серверах.

і ви завжди можете додати більше значень у Request Headers такі як Cache-Control, Origin, Accept.

Коротка відповідь:у POST-запитах значення надсилаються до «тіла» запиту. У веб-формах вони, швидше за все, відправляються з медіа-типом application/x-www-form-urlencoded або multipart/form-data. Мови програмування або фреймворки, призначені для обробки веб-запитів, зазвичай виконують «The Right Thing ™» з такими запитами та забезпечують вам легкий доступ до легко декодованих значень (наприклад, $_REQUEST або $_POST у PHP або cgi.FieldStorage() , flask .request.form у Python).

Тепер давайте трохи відвернемось, що може допомогти зрозуміти різницю;)

Різниця між запитами GET та POST значною мірою семантична. Вони також «використовуються» по-різному, що пояснює різницю у тому, як передаються значення.

GET (відповідний розділ RFC)

Під час виконання запиту GET ви запитуєте сервер для одного або набір об'єктів. Щоб клієнт міг фільтрувати результат, він може використовувати так званий рядок запиту URL-адреси. Рядок запиту є частиною після? Це частина синтаксису URI.

Отже, з погляду вашого коду програми (частина, яка отримуєзапит) вам потрібно буде перевірити частину запиту URI, щоб отримати доступ до цих значень.

Зверніть увагу, що ключі та значення є частиною URI. Браузери можутьнакладати обмеження на довжину URI. У стандарті HTTP зазначено, що обмежень немає. Але на момент написання цієї статті більшість браузерів обмежують URI (я не маю конкретних значень). Запити GET ніколи неповинні використовуватися для надсилання нової інформації на сервер. Особливо великі документи. Тут ви повинні використовувати POST або PUT.

POST (відповідний розділ RFC)

Під час виконання запиту POST клієнт фактично надсилає новий документвіддаленому хосту. Таким чином, рядок запитуне (семантично) має сенс. Ось чому у вас немає доступу до них у вашому коді програми.

POST трохи складніше (і більш гнучким):

При отриманні запиту POST ви завжди повинні чекати на «корисне навантаження», або в термінах HTTP: тіло повідомлення . Тіло повідомлення саме собою досить марне, оскільки немає стандартного(Наскільки я можу судити. Можливо, application / octet-stream?) Формата. Формат тіла визначається заголовком Content-Type. При використанні елемента HTML FORM з method="POST" це зазвичай application/x-www-form-urlencoded . Іншим дуже поширеним типом є multipart/form-data, якщо ви використовуєте завантаження файлів. Але може бути що завгодно: від text/plain , над application/json або навіть з application/octet-stream, що настроюється.

У будь-якому випадку, якщо запит POST виконується з Content-Type, який не може бути оброблений додатком, він повинен повернути код стану 415 .

Більшість мов програмування (і / або веб-фреймворки) пропонують спосіб декодування тіла повідомлення від / до найбільш поширених типів (наприклад, application/x-www-form-urlencoded , multipart/form-data або application/json) , Так що це легко. Типи користувача вимагають потенційно трохи більше роботи.

Використовуючи приклад стандартного HTML-кодованого документа, програма має виконати такі кроки:

  1. Прочитайте поле Content-Type
  2. Якщо значення не є одним з типів носіїв, що підтримуються, тоді повертайте відповідь з кодом статусу 415
  3. в іншому випадку декодувати значення з тіла повідомлення.

Знову ж таки, такі мови, як PHP, або веб-фреймворки для інших популярних мов, ймовірно, впораються з цим для вас. Винятком є ​​помилка 415 . Ніяка структура не може передбачити, які типи контенту ваш додаток вибирає для підтримки та/або не підтримки. Це залежить від вас.

PUT (відповідний розділ RFC)

Запит PUT обробляється так само, як запит POST . Велика різниця полягає в тому, що запит POST повинен дозволити серверу вирішити, як (і якщо взагалі) створити новий ресурс. Історично (з тепер застарілого RFC2616 він мав створити новий ресурс як «підлеглий» (дочірній) URI, куди відправили запит).

Передбачається, що запит PUT має «відкладати» ресурс саме вцьому URI та саме зцим контентом. Не більше не менше. Ідея полягає в тому, що клієнтвідповідає за створення повногоресурсу до "PUTting". Сервер повинен прийняти його як єна даній URL-адресі.

Як наслідок, запит POST зазвичай не використовується для заміниіснуючого ресурсу. Запит PUT може створювати ізамінювати.

Примітка

Існують також параметри шляху, які можуть використовуватися для відправки додаткових даних на пульт, але вони настільки незвичайні, що я не вдаватимуся в подробиці. Але, для довідки, ось уривок із RFC:

Крім точкових сегментів в ієрархічних шляхах, сегмент шляху вважається непрозорим за узагальненим синтаксисом. У URI, що створюють додатки, часто використовуються символи, що зарезервовані, дозволені в сегменті, для розмежування підкомпонентів, специфічних для конкретної схеми або рознесення. Наприклад, зарезервовані символи з комою (";") і одно ("=") часто використовуються для розмежування параметрів та значень параметрів, які застосовуються до цього сегменту. Зарезервований символ комою (",") часто використовується для аналогічних цілей. Наприклад, один виробник URI може використовувати сегмент, такий як name; v = 1.1», щоб вказати посилання на версію 1.1 name, тоді як інший може використовувати сегмент, такий як name, 1.1, щоб вказати його. Типи параметрів можуть бути визначені за допомогою специфічної схеми семантики, але в більшості випадків синтаксис параметра специфічний для реалізації алгоритму розіменування URI.

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

Ви можете побачити, як дані POST надсилаються в Інтернеті за допомогою заголовків HTTP, наприклад. Результат буде приблизно таким

Http://127.0.0.1/pass.php POST /pass.php HTTP/1.1 Host: 127.0.0.1 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox 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 DNT: 1 Referer: http://127.0.0.1/pass.php Cookie: passx=87e8af376bc9d9bfec2c7c0193e6af70; PHPSESSID=l9hk7mfh0ppqecg8gialak6gt5 Connection: keep-alive Content-Type: application/x-www-form-urlencoded Content-Length: 30 username=zurfyx&pass=password

Де він каже

Content-Length: 30 username=zurfyx&pass=password

будуть значення post.

Значення надсилаються в тіло запиту у форматі, вказаному у типі вмісту.

Зазвичай тип вмісту - application/x-www-form-urlencoded , тому тіло запиту використовує той самий формат, що й рядок запиту:

Parameter=value&also=another

Коли ви використовуєте завантаження файлу у формі, натомість ви використовуєте кодування multipart/form-data , яке має інший формат. Це складніше, але вам зазвичай не потрібно піклуватися про те, як це виглядає, тому я не показуватиму приклад, але може бути корисно знати, що він існує.

Тип носія за замовчуванням у запиті POST - application/x-www-form-urlencoded . Це формат для кодування пар ключ-значення. Ключі можуть бути дубльовані. Кожна пара ключ-значення поділяється символом & і кожен ключ відокремлюється від його значення символом = .

Наприклад:

Name: John Smith Grade: 19

Записується як:

Name=John+Smith&Grade=19

Він міститься в тіло запиту після заголовків HTTP.

Питання перечитує. Фактичне задане питання не схоже на префікси постачальників у властивостях CSS, де доцільно перевіряти майбутнє та думати про підтримку постачальників та офіційні стандарти. Фактичне запитання більше схоже на вибір імен параметрів запиту URL. Ніхто не повинен дбати про те, хто вони. Але збіг імен зі звичайними - це правильна, і загальна, і правильна річ.

Обґрунтування:
Мова йде про угоди між розробниками для заголовків користувача конкретних додатків - « даних, які стосуються їх облікового запису» - які не мають нічого спільного з постачальниками, органами стандартів або протоколами, які мають бути реалізовані третіми сторонами, за винятком того, що розробник, про якого йдеться просто потрібно уникати заголовків, які можуть мати інше призначення для використання серверами, проксі чи клієнтами . З цієї причини наведені приклади «X-Gzip/Gzip» та «X-Forwarded-For/Forwarded-For» є спірними. Виникає питання про угоди в контексті приватного API, аналогічні угодам про імена параметрів URL-запиту. Це питання переваги та відстані між іменами; побоювання щодо «X-ClientDataFoo», які підтримує будь-який проксі-сервер або постачальник без «X», явно недоречні.

У префіксі «X-» немає нічого особливого або чарівного, але це допомагає зрозуміти, що це заголовок, що настроюється. Насправді, RFC-6648 та ін. Допомагають запобігти використанню префіксу «X-», оскільки - оскільки постачальники HTTP-клієнтів і серверів відмовляються від префікса - ваші додатки, приватні API-інтерфейси, персональні дані, механізм передачі стає ще краще ізольованим від колізій між іменами та невеликою кількістю офіційних зарезервованих заголовків. Тим не менш, мої особисті переваги та рекомендації - зробити ще один крок і зробити, наприклад, X-ACME-ClientDataFoo (якщо ваша компанія-віджет ACME).

IMHO специфікація IETF недостатньо специфічна відповіді питання OP, оскільки він може відрізнити зовсім різні варіанти використання: (A) постачальники, впроваджують нові глобально застосовні функції, такі як «Forwarded-For», з одного боку, vs. (B) розробники додатків передають рядки, що залежать від програми, до клієнта та сервера. Спектр стосується лише першого (A). Питання тут у тому, чи існують угоди для (B). Є. Вони включають групування параметрів в алфавітному порядку та поділ їх від багатьох відповідних стандартів заголовків типу (A). Використання префікса «X-» або «X-ACME-» є зручним та законним для (B) та не суперечить (A). Чим більше продавців перестануть використовувати X- для (A), тим стануть чіткішими (B).

Приклад:
Google (які несуть трохи ваги в різних органах стандартизації) - на сьогоднішній день, 20141102 в цій незначній зміні моєї відповіді - в даний час використовується X-Mod-Pagespeed, щоб вказати версію свого модуля Apache, що бере участь в перетворюючи дану відповідь. Хто-небудь дійсно пропонує, щоб Google використовував Mod-Pagespeed без X- і / або попросив IETF благословити його використання?

Резюме:
Якщо ви використовуєте заголовки HTTP (як іноді підходящу альтернативу куки-файлам) у своєму додатку для передачі даних на ваш сервер, і ці заголовки явно не призначені для використання поза контекстом вашої програми, зіставлення імен з префіксом «X-» або «X- FOO-» є розумним та загальноприйнятим.

HTTP запит або повідомлення складається з трьох частин: рядки запиту, і тіла HTTP повідомлення.

Рядок запиту, або стартовий рядок: у запиті до сервера — рядок, який містить тип запиту (метод), URI запитуваної сторінки та версія (наприклад HTTP/1.1). У відповіді від сервера цей рядок містить версію HTTP протоколу та код відповіді. Код відповіді є цілим числом з трьох цифр. За ним зазвичай слідує відокремлена пробілом пояснювальна фраза, яка пояснює код, наприклад: 200 OK, або 404 Not Found.

Методи (типи) HTTP запитуКабіна: GET, POST, PUT, PATCH, HEAD, DELETE, TRACE. Найчастіше в HTTP запиті використовуються методи GET, або POST: GET - використовується для запиту вмісту веб-сторінки за вказаним URI. URI - це адреса сторінки без вказівки, наприклад: /internet/chto-takoe-http-zapros-soobshhenie/ замість сайт/internet/chto-takoe-http-zapros-soobshhenie/. Браузер може передавати параметри GET в URI після символу « ? »: GET /index.php?param1=value1¶m2=value2. Крім стандартного способу GET, розрізняють ще умовний GET і частковий GET. Умовні запити GET містять заголовки If-Modified-Since, If-Match, If-Range та подібні.

POST — використовується для надсилання інформації на . При надсиланні даних методом POST вони вказуються в тілі HTTP повідомлення, а не в рядку введення адреси в браузері, як це робиться при передачі даних методом GET. Наприклад, при надсиланні коментаря через форму, яка розташована під статтею, інформація на сервер передається саме методом POST. Також за допомогою методу POST завантажують файли на сервер.

— це частина запиту, в якому містяться різні параметри, які використовуються для правильної побудови веб-сторінки.

Тіло HTTP повідомлення- Містить отримані від сервера дані, наприклад сформовану web-сторінку у вигляді HTML коду, або ресурс, наприклад картинку.

Приклад HTTP повідомлень:

HTTP запит до сервера:

HTTP/1..9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 ( KHTML, як Gecko) Chrome/40.0.2150.0 Accept-Encoding: gzip, deflate, sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: wp- settings-1=hidetb%3D; wp-settings-time-1=1424958215; wordpress_test_cookie=WP+Cookie;

Відповідь від сервера:

HTTP/1.1 200 OK - стартовий рядок відповіді: Server: nginx/1.6.2 Дата: Sun, 19 Apr 2015 00:22:50 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 9431 Connection: keep-alive Keep-Alive: timeout=30 X-Powered-By: PHP/5.5.22 Expires: Wed, 11 Jan 1984 05:00:00 GMT Cache-Control: no-cache, must-revalidate.



Подібні публікації