У запиті 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буде, якщо існує ідентичний ресурс, замінить його. Тож якщо ви зателефонуєте POST10 разів, ви створите 10 ресурсів. Якщо ви телефонуєте PUT10 разів, це (можливо) створить лише один. Це відповідає на ваше запитання?
Ви не можете вводити його безпосередньо в рядку 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. Для тих, хто цікавиться, ось питання про це .