ในคำขอHTTP GETพารามิเตอร์จะถูกส่งเป็นสตริงเคียวรี :
http://example.com/page ? parameter = value & ยัง = อีก
ในคำขอHTTP POSTพารามิเตอร์จะไม่ถูกส่งไปพร้อมกับ URI
คุณค่าอยู่ที่ไหน ในส่วนหัวคำขอ? ในคำขอร่างกาย? มันดูเหมือนอะไร?
ในคำขอHTTP GETพารามิเตอร์จะถูกส่งเป็นสตริงเคียวรี :
http://example.com/page ? parameter = value & ยัง = อีก
ในคำขอ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 นั้นขึ้นอยู่กับรหัสสถานะ 418 HTTP
คำตอบสั้น ๆ :ในคำขอ POST ค่าจะถูกส่งใน "เนื้อหา" ของคำขอ กับเว็บรูปแบบที่พวกเขาจะถูกส่งไปส่วนใหญ่มีแนวโน้มที่มีประเภทของสื่อหรือapplication/x-www-form-urlencoded
multipart/form-data
การเขียนโปรแกรมภาษาหรือกรอบที่ได้รับการออกแบบมาเพื่อจัดการเว็บร้องขอมักจะทำ "สิ่งที่ถูกต้อง™" กับการร้องขอดังกล่าวและให้คุณง่ายต่อการเข้าถึงค่าถอดรหัสได้อย่างง่ายดาย (ชอบ$_REQUEST
หรือ$_POST
ใน PHP หรือcgi.FieldStorage()
, flask.request.form
ในหลาม)
ตอนนี้มาพูดนอกเรื่องเล็กน้อยซึ่งอาจช่วยให้เข้าใจความแตกต่าง;)
ความแตกต่างระหว่างGET
และPOST
คำขอส่วนใหญ่จะมีความหมาย พวกเขายัง "ใช้" แตกต่างกันซึ่งอธิบายความแตกต่างในวิธีการส่งผ่านค่า
เมื่อดำเนินการGET
ตามคำขอคุณจะขอเซิร์ฟเวอร์หนึ่งชุดหรือเอนทิตี ในการอนุญาตให้ไคลเอ็นต์กรองผลลัพธ์สามารถใช้ "query string" ของ URL ได้ ?
สตริงแบบสอบถามนี้เป็นส่วนหนึ่งหลังจากที่ นี่คือส่วนหนึ่งของไวยากรณ์ URI
ดังนั้นจากมุมมองของรหัสแอปพลิเคชันของคุณ (ส่วนที่ได้รับการร้องขอ) คุณจะต้องตรวจสอบส่วนแบบสอบถาม URI เพื่อเข้าถึงค่าเหล่านี้
โปรดทราบว่าคีย์และค่าเป็นส่วนหนึ่งของ URI เบราว์เซอร์อาจกำหนดขีดจำกัดความยาวของ URI มาตรฐาน HTTP ระบุว่าไม่มีขีด จำกัด แต่ในขณะที่เขียนนี้เบราว์เซอร์ส่วนใหญ่จะจำกัด URIs (ฉันไม่มีค่าเฉพาะ) ไม่GET
ควรใช้คำขอเพื่อส่งข้อมูลใหม่ไปยังเซิร์ฟเวอร์ ไม่เฉพาะเอกสารขนาดใหญ่ นั่นคือสิ่งที่คุณควรใช้หรือPOST
PUT
เมื่อดำเนินการPOST
ตามคำขอไคลเอนต์กำลังส่งเอกสารใหม่ไปยังรีโมตโฮสต์ ดังนั้นสตริงการสืบค้นจึงไม่สมเหตุสมผล นี่คือเหตุผลที่คุณไม่สามารถเข้าถึงได้ในรหัสแอปพลิเคชัน
POST
เป็นนิด ๆ หน่อย ๆ ที่ซับซ้อน (และอื่น ๆวิธีที่ยืดหยุ่นมากขึ้น):
เมื่อได้รับคำขอ POST คุณควรคาดหวัง "payload" หรือในแง่ HTTP: เนื้อหาข้อความเสมอ เนื้อหาของข้อความในตัวเองนั้นค่อนข้างไร้ประโยชน์เนื่องจากไม่มีมาตรฐาน (เท่าที่ฉันสามารถบอกได้อาจเป็นรูปแบบ application / octet-stream?) รูปแบบเนื้อหาถูกกำหนดโดยContent-Type
ส่วนหัว เมื่อใช้แบบ HTML FORM
element ที่นี้เป็นปกติ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 มาตรฐานเป็นตัวอย่างแอปพลิเคชันควรทำตามขั้นตอนต่อไปนี้:
Content-Type
ฟิลด์415
รหัสสถานะอีกครั้งภาษาอย่าง PHP หรือเว็บเฟรมเวิร์กสำหรับภาษายอดนิยมอื่น ๆ อาจช่วยคุณได้ ข้อยกเว้นนี้เป็น415
ข้อผิดพลาด ไม่มีกรอบงานที่สามารถทำนายประเภทเนื้อหาของแอปพลิเคชันของคุณที่เลือกให้การสนับสนุนและ / หรือไม่สนับสนุน ขึ้นอยู่กับคุณ
PUT
คำขอจะถูกจัดการสวยมากในทางเดียวกันกับการPOST
ร้องขอ ข้อแตกต่างที่สำคัญคือPOST
คำขอควรให้เซิร์ฟเวอร์ตัดสินใจว่าจะสร้างทรัพยากรใหม่ได้อย่างไร (และหากเลย) ในอดีต (จาก RFC2616 ที่ล้าสมัยในตอนนี้มันคือการสร้างทรัพยากรใหม่ในฐานะ "ผู้ใต้บังคับบัญชา" (ย่อย) ของ URI ที่คำขอถูกส่งไป)
PUT
คำขอในทางตรงกันข้ามควรจะ "เงินฝาก" ทรัพยากรตรงที่ URI ที่และตรงเนื้อหาที่ ไม่มากไม่น้อย. แนวคิดคือลูกค้ามีหน้าที่รับผิดชอบในการสร้างทรัพยากรที่สมบูรณ์ก่อนที่จะ "วาง" เซิร์ฟเวอร์ควรยอมรับตามที่เป็นอยู่ใน URL ที่กำหนด
ดังนั้นPOST
มักจะไม่ใช้คำขอเพื่อแทนที่ทรัพยากรที่มีอยู่ การPUT
ร้องขอสามารถทำได้ทั้งการสร้างและแทนที่
นอกจากนี้ยังมี " พารามิเตอร์พา ธ " ซึ่งสามารถใช้ในการส่งข้อมูลเพิ่มเติมไปยังรีโมต แต่เป็นเรื่องแปลกมากที่ฉันจะไม่เข้าไปดูรายละเอียดที่นี่มากเกินไป แต่สำหรับการอ้างอิงนี่คือข้อความที่ตัดตอนมาจาก RFC:
นอกเหนือจากจุดส่วนในเส้นทางแบบลำดับชั้นส่วนเส้นทางจะพิจารณาทึบโดยไวยากรณ์ทั่วไป แอปพลิเคชันที่ผลิต URI มักจะใช้อักขระที่สงวนไว้ซึ่งอนุญาตให้ใช้ในเซ็กเมนต์เพื่อกำหนดขอบเขตคอมโพเนนต์ย่อยเฉพาะแบบแผนหรือแบบกระจายตัวจัดการเฉพาะ ตัวอย่างเช่นอักขระเซมิโคลอน (";") และ equals ("=") มักถูกใช้เพื่อกำหนดขอบเขตพารามิเตอร์และค่าพารามิเตอร์ที่ใช้กับเซ็กเมนต์นั้น อักขระที่จองไว้ด้วยเครื่องหมายจุลภาค (",") มักใช้เพื่อจุดประสงค์เดียวกัน ตัวอย่างเช่นผู้ผลิต URI รายหนึ่งอาจใช้กลุ่มเช่น "name; v = 1.1" เพื่อระบุการอ้างอิงถึงรุ่น 1.1 ของ "ชื่อ" ในขณะที่อีกรายการหนึ่งอาจใช้กลุ่มเช่น "ชื่อ 1.1" เพื่อระบุถึงสิ่งเดียวกัน ประเภทพารามิเตอร์อาจถูกกำหนดโดยความหมายเฉพาะของโครงร่าง
PUT
ส่วนคุณจะเห็นว่ามันเป็น idempotent POST
ในทางตรงกันข้ามสามารถ - โดยคำจำกัดความ - ไม่เป็น POST
จะสร้างทรัพยากรใหม่เสมอ PUT
จะหากทรัพยากรที่เหมือนกันมีอยู่แทนที่มัน ดังนั้นถ้าคุณโทรPOST
10 ครั้งคุณจะสร้างทรัพยากร 10 ครั้ง หากคุณโทรมาPUT
10 ครั้งมันจะ (อาจ) สร้างเพียงครั้งเดียว นั่นตอบคำถามของคุณหรือไม่
คุณไม่สามารถพิมพ์ได้โดยตรงบนแถบ URL ของเบราว์เซอร์
คุณสามารถดูว่าข้อมูล POST ถูกส่งบนอินเทอร์เน็ตด้วยLive HTTP Headersได้อย่างไร ผลลัพธ์จะเป็นอย่างนั้น
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 POSTs จะถูกส่งไปในเนื้อความการร้องขอในรูปแบบเดียวกับการสอบถาม
?
ตัวอย่าง?
application/x-www-form-urlencoded
กรณีที่ไม่เสมอไป
เว็บเซอร์วิสบางแห่งกำหนดให้คุณวางข้อมูลคำขอและข้อมูลเมตาแยกจากกัน ตัวอย่างเช่นฟังก์ชั่นระยะไกลอาจคาดหวังว่าสตริงเมทาดาทาที่ลงนามแล้วจะรวมอยู่ใน URI ในขณะที่โพสต์ข้อมูลใน HTTP-body
คำขอ 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 ด้วยการใช้ single Content-Type
ซึ่งเป็น "การแยกวิเคราะห์คำสั่ง" สำหรับเว็บเซิร์ฟเวอร์
โปรดทราบ: HTTP / 1.1 ถูกห่อด้วย#32
(ช่องว่าง) ทางด้านซ้ายและด้วย#10
(ตัวดึงบรรทัด) ทางด้านขวา
/user/john
และ/?user=john
เป็นเพียงความหมาย (HTTP ไม่ได้ให้การรักษาแบบพิเศษกับสตริงข้อความค้นหา) ดังนั้นฉันจึงคาดหวังสิ่งนี้ตามสมควร แต่คุณหมายถึงอะไรโดย "ห่อด้วยพื้นที่ทางด้านซ้าย"? ไม่มีช่องว่างหน้าเมธอด HTTP คุณหมายถึงบรรทัดว่างสำหรับโพสต์เนื้อหาหรือไม่
...Ym04
และHTTP/1.1
ในโค้ดด้านบน ดังนั้น QueryString จะอยู่ระหว่างกริยาและเวอร์ชันโปรโตคอล
?
เราทำกับGET
คำขอ
ก่อนอื่นเรามาแยกความแตกต่างระหว่างGET
และPOST
ได้รับ:มันเป็นค่าเริ่มต้นHTTP
การร้องขอที่ทำไปยังเซิร์ฟเวอร์และถูกนำมาใช้ในการดึงข้อมูลจากเซิร์ฟเวอร์และแบบสอบถามสตริงที่มาหลังจาก?
ในURI
จะใช้ในการดึงทรัพยากรที่ไม่ซ้ำกัน
นี่คือรูปแบบ
GET /someweb.asp?data=value HTTP/1.0
นี่data=value
คือค่าสตริงแบบสอบถามที่ส่งผ่าน
โพสต์:มันถูกใช้เพื่อส่งข้อมูลไปยังเซิร์ฟเวอร์อย่างปลอดภัยดังนั้นสิ่งที่จำเป็นนี่คือรูปแบบของการ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
ทำไมโพสต์มากกว่า 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
คำตอบของคุณจะเพียงพอในขณะที่มันจะดีเป็นพิเศษถ้ามันมีข้อมูลเพิ่มเติมเกี่ยวกับ สำหรับผู้ที่สนใจ แต่นี่เป็นคำถามเกี่ยวกับเรื่องนี้