日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Multipart/form-data POST文件上传详解

發布時間:2024/2/28 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Multipart/form-data POST文件上传详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Multipart/form-data POST文件上傳詳解

理論

簡單的HTTP POST

大家通過HTTP向服務器發送POST請求提交數據,都是通過form表單提交的,代碼如下:

<form method="post"action="http://w.sohu.com" >

???????? <inputtype="text" name="txt1">

???????? <inputtype="text" name="txt2">

?</form>

提交時會向服務器端發出這樣的數據(已經去除部分不相關的頭信息),數據如下:

?

POST / HTTP/1.1

Content-Type:application/x-www-form-urlencoded

Accept-Encoding: gzip, deflate

Host: w.sohu.com

Content-Length: 21

Connection: Keep-Alive

Cache-Control: no-cache

?

txt1=hello&txt2=world

?

對于普通的HTML Form POST請求,它會在頭信息里使用Content-Length注明內容長度。頭信息每行一條,空行之后便是Body,即“內容”(entity)。它的Content-Type是application/x-www-form-urlencoded,這意味著消息內容會經過URL編碼,就像在GET請 求時URL里的QueryString那樣。txt1=hello&txt2=world

POST上傳文件

最早的HTTP POST是不支持文件上傳的,給編程開發帶來很多問題。但是在1995年,ietf出臺了rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上傳。所以Content-Type的類型擴充了multipart/form-data用以支持向服務器發送二進制數據。因此發送post請求時候,表單<form>屬性enctype共有二個值可選,這個屬性管理的是表單的MIME編碼:

?①application/x-www-form-urlencoded(默認值)
?②multipart/form-data
其實form表單在你不寫enctype屬性時,也默認為其添加了enctype屬性值,默認值是enctype="application/x- www-form-urlencoded".

?

通過form表單提交文件操作如下:

<form method="post"action="http://w.sohu.com/t2/upload.do" enctype=”multipart/form-data”>

???????? <inputtype="text" name="desc">

???????? <inputtype="file" name="pic">

?</form>

?

瀏覽器將會發送以下數據:

POST /t2/upload.do HTTP/1.1

User-Agent: SOHUWapRebot

Accept-Language: zh-cn,zh;q=0.5

Accept-Charset: GBK,utf-8;q=0.7,*;q=0.7

Connection: keep-alive

Content-Length: 60408

Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC

Host: w.sohu.com

?

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC

Content-Disposition: form-data;name="desc"

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

Content-Transfer-Encoding: 8bit

?

[......][......][......][......]...........................

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC

Content-Disposition: form-data;name="pic"; filename="photo.jpg"

Content-Type: application/octet-stream

Content-Transfer-Encoding: binary

?

[圖片二進制數據]

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--

?

我們來分析下數據,第一個空行之前自然還是HTTP header,之后則是Entity,而此時的Entity也比之前要復雜一些。根據RFC 1867定義,我們需要選擇一段數據作為“分割邊界”( boundary屬性),這個“邊界數據”不能在內容其他地方出現,一般來說使用一段從概率上說“幾乎不可能”的數據即可。 不同瀏覽器的實現不同,例如火狐某次post的? boundary=---------------------------32404670520626 , opera為boundary=----------E4SgDZXhJMgNE8jpwNdOAX ,每次post瀏覽器都會生成一個隨機的30-40位長度的隨機字符串,瀏覽器一般不會遍歷這次post的所有數據找到一個不可能出現在數據中的字符串,這樣代價太大了。一般都是隨機生成,如果你遇見boundary值和post的內容一樣,那樣的話這次上傳肯定失敗,不過我建議你去買彩票,你太幸運了。Rfc1867這樣說明{A boundary is selected that does not occur in any of the data. (This selection is sometimes done probabilisticly.)}。

?

?

選擇了這個邊界之后,瀏覽器便把它放在Content-Type 里面傳遞給服務器,服務器根據此邊界解析數據。下面的數據便根據boundary劃分段,每一段便是一項數據。(每個field被分成小部分,而且包含一個value是"form-data"的"Content-Disposition"的頭部;一個"name"屬性對應field的ID,等等,文件的話包括一個filename)

  • IE和Chrome在filename的選擇策略上有所不同,前者是文件的完整路徑,而后者則僅僅是文件名。
  • 數據內容以兩條橫線結尾,并同樣以一個換行結束。在網絡協議中一般都以連續的CR、LF(即\r、\n,或0x0D、Ox0A)字符作為換行,這與Windows的標準一致。如果您使用其他操作系統,則需要考慮它們的換行符。

?另外Content-length 指的是所用數據的長度。

實現

httpClient4如何實現

httpClient4使用http-mime.jar包的MultipartEntity實現,代碼如下(為了簡潔,處理了異常處理代碼):

???????????????????????????

HttpPost httpPost = newHttpPost(url);

Log.debug("post url:"+url);

httpPost.setHeader("User-Agent","SOHUWapRebot");

httpPost.setHeader("Accept-Language","zh-cn,zh;q=0.5");

httpPost.setHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.7");

httpPost.setHeader("Connection","keep-alive");

?

MultipartEntity mutiEntity = newMultipartEntity();

File file = new File("d:/photo.jpg");

mutiEntity.addPart("desc",new StringBody("美麗的西雙版納", Charset.forName("utf-8")));

mutiEntity.addPart("pic", newFileBody(file));

?

?

httpPost.setEntity(mutiEntity);

HttpResponse? httpResponse = httpClient.execute(httpPost);

HttpEntity httpEntity =? httpResponse.getEntity();

String content = EntityUtils.toString(httpEntity);

???????????????????????????

??????????????????

?

參考:

Rfc1867:http://www.ietf.org/rfc/rfc1867

Rfc1867:http://www.vivtek.com/rfc1867.html

?

總結

以上是生活随笔為你收集整理的Multipart/form-data POST文件上传详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。