post請求四種傳送正文的方式


一、簡介

  HTTP協議規定post提交的數據必須放在消息主體(entity-body)中,但協議沒有規定數據必須使用什么編碼方式。HTTP協議是以ASCII碼傳輸,建立再TCP/IP協議之上的應用層規范。HTTP請求分為3個部分:狀態行、請求頭和消息主體。類似於:

<method> <request-URL> <version> <headers> <entity-body>  

  服務端通常是根據請求頭(header)中的Content_Type字段來獲取請求中的消息主體是用何種方式編碼,再對消息主體進行解析。

二、瀏覽器form表單提交

  1.form表單常用屬性如下:

  action:url 地址,服務器接收表單數據的地址
  method:提交服務器的http方法,一般為post和get
  name:
  enctype: 表單數據提交時使用的編碼類型,默認使用"application/x-www-form-urlencoded",如果是使用POST請求,則請求頭中的content-type指定值就是該值。如果表單中有上傳文件,編碼類型需要使用"multipart/form-data",類型,才能完成傳遞文件數據。

  PS:enctype為form表單數據的編碼格式,Content-type為HTTP傳輸的數據的編碼格式,要分清兩者!!!

  2.瀏覽器提交表單時,會執行如下步驟:

  ① 識別出表單中表單元素的有效項,作為提交項

  ② 構建一個表單數據集

  ③ 根據form表單中enctype屬性的值作為content-type屬性的值作為content-type對數據進行編碼

  ④ 根據form表單中的action屬性和method屬性向指定的url地址發送數據

  3.提交方式的不同

  ① get:表單數據會被encodeURIComponent后以參數的形式:name1=value1&name2=value2附帶在url?后面,再發送給服務器,並在url中顯示出來。

  ② post:enctype默認“application/x-www-form-urlencoded”對表單數據進行編碼,數據以鍵值對在http請求中發送給服務器;如果enctype屬性為“multipart/form-data”,則以消息的形式發送給服務器。

三、常見的四種編碼方式

  1.application/x-www-form-urlencoded

  最常見的post提交數據的編碼方式。瀏覽器的原生form表單,若不設置enctype屬性,默認以application/x-www-form-urlencoded編碼方式提交數據。for example:

   POST http://www.example.com HTTP/1.1    
  Content-Type:application/x-www-form-urlencoded;charset=utf-8   title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

  2.multipart/form-data

  除了傳統的application/x-www-form-urlencoded表單,另一個常用的是上傳文件用的表單,其表單類型為multipart/form-data. for example:

   <form action="/upload" enctype="multipart/form-data" method="post">
       Username: <input type="text" name="username">
       Password: <input type="password" name="password">
       File: <input type="file" name="file">
       <input type="submit">
   </form>

  3.application/json

  4.text/xml

四、post請求四種傳送正文方式

  1.請求正文是application/x-www-form-urlencoded

  形式:requests.post(url='',data={'key1':'value1','key2':'value2'},headers={'Content-Type':'multipart/form-data'})
  requests支持以form表單形式發送post請求,只需要將請求的參數構造成一個字典,然后傳給requests.post()的data參數即可
import requests
url = "http://httpbin.org/post"
data = {"key1":"value1","key2":"value2"}
headers = {"Content-type":"application/x-www-form-urlencoded"}
r = requests.post(url=url,data=data,headers=headers)
print(r.text)

 

  由上圖可以看到,請求頭中的Content-Type字段已設置為application/x-www-form-urlencoded,且data = {'key1': 'value1', 'key2': 'value2'}以form表單的形式提交到服務端,服務端返回的form字段即是提交的數據。

  2.請求正文是multipart/form-data

  形式:

requests.post(url='',data={'key1':'value1','key2':'value2'},headers={'Content-Type':'multipart/form-data'})
from requests_toolbelt import MultipartEncoder
import requests
url="http://httpbin.org/post"
m = MultipartEncoder(fields={"field0":"value","field1":"value"})     # 刪掉fields效果一樣
headers = {"Content-Type":m.content_type}
r = requests.post(url=url,data = m,headers=headers)
print(r.text)

  

  3.請求正文是raw

  形式:

  ① 傳入xml格式文本(可擴展性語言:Extensible markup language)

requests.post(url='',data='<?xml  ?>',headers={'Content-Type':'text/xml'})

  ② 傳入json格式文本

requests.post(url='',data=json.dumps({'key1':'value1','key2':'value2'}),headers={'Content-Type':'application/json'})
或:requests.post(url='',json={{'key1':'value1','key2':'value2'}},headers={'Content-Type':'application/json'})

  for example:

import requests
import json
url = "http://httpbin.org/post"
j = {"key1":"value1","key2":"value2"}
data = json.dumps(j)  # json模塊下的dumps函數將dict轉換為str
headers = {"Content-type":"application/json"}
r = requests.post(url=url,data=data,json=j,headers=headers)
print(r.text)

  PS:腳本中dumps不要寫成dump,否則會報缺失fp(類文件指針)的錯誤

  python中json.dumps()和json.dump()的區別:      https://www.cnblogs.com/fengff/p/11008353.html

 

  4.請求正文是binary

  形式:

requests.post(url='',files={'file':open('test.xls','rb')},headers={'Content-Type':'binary'})
import requests
url = "http://httpbin.org/post"
files = {"file":open("test.xlsx","rb")}
headers = {"Content-type":"binary"}
r = requests.post(url=url,files=files,headers=headers)
print(r.text)

   另外,requests也支持multipart方式發送post請求,只需將一文件傳給requests.post()的參數files即可。 

import requests
url = "http://httpbin.org/post"
files = {"file":open("report.txt","rb")}
r = requests.post(url=url,files=files)
print(r.text)

PS:為了避免文件路徑的問題,建議文件直接放在當前py文件的同一級目錄下。

 

 

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM