背景: 想通过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();
}
至此数据上传完毕!