У запиті HTTP GET параметри надсилаються як рядок запиту :
http://example.com/page ? параметр = значення & також = інший
У запиті HTTP POST параметри не надсилаються разом з URI.
Де значень? У заголовку запиту? У органі запиту? На що це схоже?
У запиті HTTP GET параметри надсилаються як рядок запиту :
http://example.com/page ? параметр = значення & також = інший
У запиті HTTP POST параметри не надсилаються разом з URI.
Де значень? У заголовку запиту? У органі запиту? На що це схоже?
Відповіді:
Значення надсилаються в тіло запиту у форматі, який задає тип вмісту.
Зазвичай тип вмісту є application/x-www-form-urlencoded
, тому тіло запиту використовує той самий формат, що і рядок запиту:
parameter=value&also=another
Під час завантаження файлу у формі ви використовуєте multipart/form-data
кодування, яке має інший формат. Це складніше, але вам зазвичай не потрібно дбати про те, як це виглядає, тому я не показуватиму приклад, але можна добре знати, що він існує.
multipart/form-data
або якщо ви відповідаєте за створення запиту, змініть тип вмісту application/json
та вставте текст json безпосередньо в тіло http
Вміст розміщується після заголовків HTTP. Формат HTTP POST має містити заголовки HTTP, за якими слідує порожній рядок, за яким йде орган запиту. Змінні POST зберігаються як пари ключових значень у тілі.
Ви можете бачити це у вихідному вмісті повідомлення HTTP, показаному нижче:
POST /path/script.cgi HTTP/1.0
From: frog@jmarshall.com
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
home=Cosby&favorite+flavor=flies
Ви можете побачити це за допомогою інструменту типу Fiddler , який можна використовувати для перегляду необробленого HTTP-запиту та корисних навантажень відповідей, що надсилаються по всій лінії зв'язку.
application/x-www-form-urlencoded
, що не завжди так.
From
там заголовок?
From
заголовка. IMO, там з кодом статусу HTTP 418.
Коротка відповідь: у POST-запитах значення надсилаються у "тіло" запиту. За допомогою веб-форм вони, швидше за все, надсилаються з мультимедійним типом application/x-www-form-urlencoded
або multipart/form-data
. Мови програмування або рамки , які були призначені для обробки веб-запитів , як правило , роблять «The Right Thing ™» з такими запитами і надати вам легкий доступ до легко розшифрованих значень (наприклад , $_REQUEST
чи $_POST
в PHP, або cgi.FieldStorage()
, flask.request.form
в Python).
Тепер трохи підемо на розгляд, що може допомогти зрозуміти різницю;)
Різниця між запитами GET
та POST
запитами значною мірою семантична. Вони також "використовуються" по-різному, що пояснює різницю в передачі значень.
Виконуючи GET
запит, ви запитуєте сервер для одного чи набору сутностей. Щоб дозволити клієнту фільтрувати результат, він може використовувати так звану "рядок запиту" URL-адреси. Рядок запиту - це частина після ?
. Це частина синтаксису URI .
Отже, з точки зору коду вашої програми (частини, яка отримує запит), вам потрібно буде перевірити частину запиту URI, щоб отримати доступ до цих значень.
Зауважте, що ключі та значення є частиною URI. Веб-переглядачі можуть встановити обмеження на довжину URI. Стандарт HTTP зазначає, що обмеження немає. Але на момент написання цієї статті, більшість браузерів дійсно обмежують ідентифікатори URI (я не маю конкретних значень). GET
запити ніколи не повинні використовуватися для подання нової інформації на сервер. Особливо не більші документи. Ось де ви повинні використовувати POST
або PUT
.
Виконуючи POST
запит, клієнт фактично подає новий документ віддаленому хосту. Отже, рядок запиту не має (семантично) сенсу. Ось чому ви не маєте доступу до них у коді програми.
POST
трохи складніший (і спосіб більш гнучкий):
Отримуючи запит POST, ви завжди повинні очікувати "корисного навантаження", або, HTTP термінів: тіла повідомлення . Тіло повідомлення само по собі є досить марним, оскільки немає стандартного (наскільки я можу сказати. Може бути, програми / octet-stream?) Формату. Формат тіла визначається Content-Type
заголовком. При використанні FORM
елемента HTML з method="POST"
, як правило, це application/x-www-form-urlencoded
. Ще один дуже поширений тип - це багаточастинні / форма-дані, якщо ви використовуєте завантаження файлів. Але це може бути що завгодно , починаючи від text/plain
, закінчуючи application/json
або навіть звичай application/octet-stream
.
У будь-якому випадку, якщо POST
запит зроблено із Content-Type
програмою, з якою програма не може оброблятися, вона повинна повернути 415
код статусу .
Більшість мов програмування (та / або веб-фреймів) пропонують спосіб декодування / кодування тіла повідомлення від / до найпоширеніших типів (наприклад application/x-www-form-urlencoded
, multipart/form-data
або application/json
). Так що це легко. Спеціальні типи вимагають трохи більше роботи.
Використовуючи стандартний документ, кодований формою HTML, наприклад, додаток повинен виконати наступні дії:
Content-Type
поле415
кодом статусуЗнову ж таки, такі мови, як PHP або веб-рамки для інших популярних мов, ймовірно, справляться з вами. Виняток з цього - 415
помилка. Жодна рамка не може передбачити, які типи вмісту ваша програма обирає та / або не підтримує. Це залежить від вас.
PUT
Запит в значній мірі обробляються точно так же, як POST
запит. Велика різниця полягає в тому, що POST
запит повинен дозволити серверу вирішити, як (і якщо взагалі) створити новий ресурс. Історично (з застарілого RFC2616 було створено новий ресурс як "підлеглий" (дочірній) URI, куди було направлено запит).
PUT
Запит на відміну передбачається «депозит» ресурс саме на цьому URI, і саме це зміст. Ні більше, ні менше. Ідея полягає в тому, що клієнт несе відповідальність за розробку повного ресурсу перед тим, як "ВСТУПИТИ" його. Сервер повинен прийняти це так, як є за вказаною URL-адресою.
Як наслідок, POST
запит зазвичай не використовується для заміни наявного ресурсу. PUT
Запит може зробити як створити і замінити.
Є також " параметри шляху ", які можна використовувати для надсилання додаткових даних на віддалений, але вони настільки рідкісні, що я тут не буду надто детально описуватись. Але для довідки, ось уривок із RFC:
Крім точкових сегментів в ієрархічних шляхах, загальний синтаксис відрізок шляху вважається непрозорим. У додатках, що виробляють URI, часто використовуються зарезервовані символи, дозволені в сегменті, для розмежування підкомпонентів, що стосуються схеми або специфічного для оброблювача. Наприклад, знаки з комою (";") і рівні ("=") зарезервовані символи часто використовуються для розмежування параметрів і значень параметрів, застосовних до цього сегмента. Кома (",") зарезервований символ часто використовується для подібних цілей. Наприклад, один виробник URI може використовувати сегмент, такий як "name; v = 1.1", щоб вказати на посилання на версію 1.1 "name", тоді як інший може використовувати сегмент, такий як "name, 1.1" для позначення того ж. Типи параметрів можуть бути визначені семантикою, що залежить від схеми,
PUT
розділі, ви побачите , що вона є ідемпотентів. POST
на відміну може - за визначенням - не бути. POST
завжди створить новий ресурс. PUT
буде, якщо існує ідентичний ресурс, замінить його. Тож якщо ви зателефонуєте POST
10 разів, ви створите 10 ресурсів. Якщо ви телефонуєте PUT
10 разів, це (можливо) створить лише один. Це відповідає на ваше запитання?
Ви не можете вводити його безпосередньо в рядку URL-адреси веб-переглядача.
Ви можете бачити, як дані POST надсилаються в Інтернет, наприклад, із заголовками HTTP Live Live . Результат буде чимось подібним
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/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
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
будуть значеннями публікації.
Content-Length
має бути 29
тут? Це фактична довжина струни username=zurfyx&pass=password
.
Типом носія за замовчуванням у запиті POST є application/x-www-form-urlencoded
. Це формат для кодування пар ключ-значення. Клавіші можуть бути дублюючими. Кожна пара ключ-значення розділена &
символом, а кожен ключ відокремлений від свого значення =
символом.
Наприклад:
Name: John Smith
Grade: 19
Кодується як:
Name=John+Smith&Grade=19
Це розміщується в тілі запиту після заголовків HTTP.
Значення форми в HTTP POST надсилаються в тіло запиту в тому ж форматі, що і рядок запитів.
Для отримання додаткової інформації див. Специфікацію .
?
прикладу?
application/x-www-form-urlencoded
, що не завжди так.
Деякі веб-сервіси вимагають розміщення даних запиту та метаданих окремо. Наприклад, віддалена функція може очікувати, що підписаний рядок метаданих буде включений в 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 (compatible; Indy Library)
name id
John G12N
Sarah J87M
Bob N33Y
Цей підхід логічно поєднує QueryString та Body-Post, використовуючи єдиний, Content-Type
який є "інструкцією розбору" для веб-сервера.
Будь ласка , зверніть увагу: HTTP / 1.1 обгорнутий з #32
(пропуск) на лівій і з #10
(рядки) праворуч.
/user/john
і /?user=john
є лише семантичною (HTTP насправді не дає особливого трактування рядків запитів), тому я сприймаю це як розумно очікуване. Але що ви маєте на увазі під "загорнутим простором зліва"? Перед методом HTTP немає пробілів. Ви маєте на увазі порожній рядок для тіла повідомлення?
...Ym04
та HTTP/1.1
у вказаному вище коді є пробіл (ASCII # 32) . Таким чином, QueryString просто знаходиться між дієсловом та версією протоколу.
?
як ми це робимо із GET
запитами.
Перш за все, давайте розмежуємо між GET
іPOST
Отримати: це HTTP
запит за замовчуванням, який робиться на сервер і використовується для отримання даних із сервера та рядка запиту, що надходить ?
у a 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 //you can put any format here
Content-Length: 11 //it depends
Name= somename
Чому POST над GET?
У GET
значенні, яке надсилається серверам, зазвичай додається до базової URL-адреси в рядку запиту, тепер є 2 наслідки цього
GET
запити зберігаються в історії браузера з параметрами. Таким чином ваші паролі залишаються незашифрованими в історії браузера. Це було справжньою проблемою для Facebook ще в ті часи.URI
. Якщо ви надсилаєте занадто багато параметрів, ви можете отримати414 Error - URI too long
У разі надсилання запиту ваші дані з полів замість цього додаються до тіла. Довжина параметрів запиту обчислюється та додається до заголовка для довжини вмісту, а до URL-адреси безпосередньо не додаються важливі дані.
Ви можете скористатися розділом мережі Інструменти для розробників Google, щоб переглянути основні відомості про те, як надходять запити до серверів.
і ви завжди можете додати більше значення в вашому Request Headers
Як і Cache-Control
, Origin
, Accept
.
HTTPS
зв'язку, не так HTTP
. HTTPS
шифрує як URL
(включаючи параметри запитів), так і Request Body
, коли HTTP
шифрує / не захищає жодного. Описана проблема пов'язана з тим, що багато браузерів зберігають URIs
(включаючи URLs
) у своїх базах даних історії (як правило, не зашифровані). Тож використовуйте лише Request Body
+ HTTPS
для нічого чутливого.
multipart/form-data
. Для тих, хто цікавиться, ось питання про це .