背景: 想通過httpwebrequest 模擬圖片上傳到某網站
1)首先要通過抓包工具,找到上傳圖片時候上傳的數據格式
這里使用Fillder抓包,瀏覽器代理127.0.0.1:8888
要上傳的圖片名字為: 20120810111939871.jpg 在D盤下
圖1. 請求的頭部。 獲取圖片上傳地址,帶上cookie,設置 context-Length,Context-Type
圖2. 上傳的body數據。一定要注意格式。 該有空格,換行,就一定要有,否則上傳會失敗或者毫無響應。
點擊 Raw,可以查看上傳了具體哪些數據,包括 http header 和http body。
如果你上傳失敗,此處應該查看模擬上傳時候的Raw 數據 和 正常網站上傳圖片時候 有哪些格式不對。(包括換行和某些空格哦,切記)
(微軟有compare軟件,用於比較2個不同)
下面開始寫上傳圖片的代碼
1)設置http header。 指定上傳地址,帶上cookie,指定ContentType = "multipart/form-data; …
2)設置上傳圖片的form 中的所有input 數據;
上傳的數據如下,一定要格式。
------WebKitFormBoundaryRLGpV3Skhw9DrOMs
Content-Disposition: form-data; name="ck"
mo9u //上傳form中的ck 的值
------WebKitFormBoundaryRLGpV3Skhw9DrOMs
Content-Disposition: form-data; name="picfile"; filename="20120810111939871.jpg"
Content-Type: image/jpeg
這兒是圖片的二進制編碼
------WebKitFormBoundaryRLGpV3Skhw9DrOMs
Content-Disposition: form-data; name="icon_submit"
上傳照片
------WebKitFormBoundaryRLGpV3Skhw9DrOMs
Content-Disposition: form-data; name="ck"
mo9u
------WebKitFormBoundaryRLGpV3Skhw9DrOMs
Content-Disposition: form-data; name="imgpos"
6_8_128
------WebKitFormBoundaryRLGpV3Skhw9DrOMs--
所以分為3步分解數據。1. 圖片之前的部分值。 2 圖片二進制數據 3. 圖片二進制數據之后的值
public void MyUploader(string strFileToUpload, string strUrl, CookieContainer cc)
{
//第一步
string strFileFormName = "file";
Uri oUri = new Uri(strUrl);
string strBoundary = "----WebKitFormBoundary" + "0vLxY1AmJKo0M2nx";//DateTime.Now.Ticks.ToString("X2");
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(strUrl);
webrequest.Method = "post";
webrequest.ContentType = "multipart/form-data; boundary=" + strBoundary + "";
webrequest.Referer = "http://www.douban.com/accounts/user_icon/";
webrequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11";
webrequest.CookieContainer = cc;
//第一步結束
// The post message header
StringBuilder sb = new StringBuilder();
sb.Append("--");
sb.Append(strBoundary);
sb.Append("\r\n");
sb.Append("Content-Disposition: form-data; name=\"ck\"");
sb.Append("\r\n");
sb.Append("\r\n");
sb.Append(ck);
sb.Append("\r\n");
sb.Append("--");
sb.Append(strBoundary);
sb.Append("\r\n");
sb.Append("Content-Disposition: form-data; name=\"picfile\";filename=\"");
sb.Append(Path.GetFileName(strFileToUpload));
sb.Append("\"");
sb.Append("\r\n");
sb.Append("Content-Type: ");
sb.Append("image/jpeg");
sb.Append("\r\n");
sb.Append("\r\n");
string strPostHeader = sb.ToString();
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(strPostHeader);
StringBuilder sbBoun = new StringBuilder();
sbBoun.Append("\r\n");
sbBoun.Append("--");
sbBoun.Append(strBoundary);
sbBoun.Append("\r\n");
sbBoun.Append("Content-Disposition: form-data; name=\"icon_submit\"");
sbBoun.Append("\r\n");
sbBoun.Append("\r\n");
sbBoun.Append("上傳照片");
sbBoun.Append("\r\n");
sbBoun.Append("--");
sbBoun.Append(strBoundary);
sbBoun.Append("\r\n");
sbBoun.Append("Content-Disposition: form-data; name=\"ck\"");
sbBoun.Append("\r\n");
sbBoun.Append("\r\n");
sbBoun.Append(ck);
sbBoun.Append("\r\n");
sbBoun.Append("--");
sbBoun.Append(strBoundary);
sbBoun.Append("\r\n");
sbBoun.Append("Content-Disposition: form-data; name=\"imgpos\"");
sbBoun.Append("\r\n");
sbBoun.Append("\r\n");
sbBoun.Append(imgpos);
sbBoun.Append("\r\n");
sbBoun.Append("--");
sbBoun.Append(strBoundary);
sbBoun.Append("--");
sbBoun.Append("\r\n");
//sbBoun.Append("\r\n");
//byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + strBoundary + "\r\n");
byte[] boundaryBytes = Encoding.ASCII.GetBytes(sbBoun.ToString());
//紅色的都是為 圖片數據的處理
FileStream fileStream = new FileStream(strFileToUpload, FileMode.Open, FileAccess.Read);
long length = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length;
webrequest.ContentLength = length;
Stream requestStream = webrequest.GetRequestStream();
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
byte[] buffer = new Byte[(int)fileStream.Length];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
requestStream.Close();
//將3個數據分段寫入 requestStream; 其中 2個數據直接就是byte[]格式寫入。
// 圖片先要通過fileStream 獲取圖片的byte[],然后將filestream 寫如byte[],然后再寫入requestStream
HttpWebResponse res = (HttpWebResponse)webrequest.GetResponse();
StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.Default);
sb.Append(sr.ReadToEnd());
res.Close();
webrequest.Abort();
}
至此數據上傳完畢!