HTTP POST上傳文件說明及注意事項


這一陣子因為項目需要要對接別家公司的restful接口,其中有一個接口是上傳視頻文件。接着上網找找資料。后來文件是上傳成功了,但上服務器一看,文件沒有后綴,我勒個去,這是什么個鬼。接着繼續找資料,最終發現是因為在文件數據后面沒加上“\r\n”引起的,特發此博文備忘。在此感謝【小伊同學】的《c#代碼發送post請求,上傳文件》https://www.cnblogs.com/yinq/p/6045995.html和【imEgo】的《HTTP POST上傳文件格式說明》http://blog.sina.com.cn/s/blog_73b633110101jwxm.html。

 1 public static Response FileLoadRequest(string url, string filePath, string rename = "")
 2 {
 3     Response httpResponse = null;
 4     string fileName = FileHelper.GetFileName(filePath);
 5     string boundary = "ceshi";
 6     string Enter = "\r\n";
 7 
 8     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
 9     request.Method = "POST";
10     request.ContentType = "multipart/form-data;charset=utf8;boundary=" + boundary;  //boundary這個屬性很重要
11     //進行Session持久化
12     request.CookieContainer = cookie;
13 
14     #region 將參數寫入請求流中
15     Stream RequestStream = request.GetRequestStream();
16     string fileContentStr = "--" + boundary + Enter
17             + "Content-Type:application/octet-stream" + Enter
18             + "Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"" + Enter + Enter;
19     var fileContentStrByte = Encoding.UTF8.GetBytes(fileContentStr);
20 
21     FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
22     byte[] filedata = new byte[fs.Length];
23     fs.Read(filedata, 0, Convert.ToInt32(fs.Length));
24     fs.Close();
25 
26     RequestStream.Write(fileContentStrByte, 0, fileContentStrByte.Length);
27     RequestStream.Write(filedata, 0, filedata.Length);
28 
29     //在文件數據末尾要加上“\r\n”
30     string EndStr1 = Enter;
31     var EndStr1Byte = Encoding.UTF8.GetBytes(EndStr1);
32     RequestStream.Write(EndStr1Byte, 0, EndStr1Byte.Length);
33 
34     if (rename != "")
35     {
36         string fileNameStr = "--" + boundary + Enter
37             + "Content-Disposition: form-data; name=\"file_name\"" + Enter + Enter
38             + rename;
39         var fileNameStrByte = Encoding.UTF8.GetBytes(fileNameStr);
40         RequestStream.Write(fileNameStrByte, 0, fileNameStrByte.Length);
41     }
42 
43     //在流末尾要加上--ceshi--的分隔符
44     string EndStr = Enter + "--" + boundary + "--";
45     var EndStrByte = Encoding.UTF8.GetBytes(EndStr);
46     RequestStream.Write(EndStrByte, 0, EndStrByte.Length);
47     #endregion
48 
49     string responseMessage = string.Empty;
50     try
51     {
52         using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
53         {
54 
55             StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
56             responseMessage = sr.ReadToEnd();
57             httpResponse = JsonConvert.DeserializeObject<Response>(responseMessage);
58             response.Close();
59         }
60     }
61     catch (WebException ex)
62     {
63         Program.log.Error(string.Format("System.Net.WebException:UrlGetRequest出錯,URL='{0}':", request.RequestUri), ex);
64     }
65     catch (Exception ex)
66     {
67         Program.log.Error(string.Format("UrlGetRequest出錯,URL='{0}':", request.RequestUri), ex);
68     }
69 
70     return httpResponse;
71 }

下面引用下RFC的Sample:

Content-Type: multipart/form-data, boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="field1"

Joe Blow
--AaB03x
Content-Disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain

 ... contents of file1.txt ...
--AaB03x--

首先,在Content-Type中,boundary這個屬性一定要加,但boundary屬性值隨意設置成什么都行,它不會出現在要上傳的數據里,只是起到分隔的作用。上面是設置成“Aab03x”。重點來了:每個參數之前需要加上“--boundary”,注意前面有“--”。參數最后結尾要加“--boundary--”。文件數據后要跟上“\r\n”(我就是因為沒加“\r\n,所以沒有文件后綴”)在上傳文件的那一個參數的Content-Type:是根據上傳文件的后綴進行設置的,詳細對照表請參照:http://tool.oschina.net/commons/。如果不想根據文件后綴進行填充的話,可以直接用“application/octet-stream”。


免責聲明!

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



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