您的位置:首页 > 其它

form标签属性enctype之multipart/form-data请求详解

2017-05-08 17:54 513 查看
当form标签的enctype设置为multipart/form-data浏览器都干了些什么呢?

    通常我们在做向服务器提交数据的功能时都会用到表单提交,默认情况下表单的enctype属性值为application/x-www-form-urlencoded,在想服务器发送数据前,所有的字符都会进行编码(空格转换为“+”号,特殊符号转换为ASCII HEX值,如“<”会转换为“%3C”);但是当我们想要做一个的包含上传的数据提交功能时,就必须要将form标签的enctype属性设置为multipart/form-data才可以,那么此时浏览器都干了些什么,接下来我们抓取一下提交表单时的请求,如下图所示:



在请求头中我们发现Content-Type后面的值中有boundary的键后面跟着一串“不明所以”的字符,在Requset PayLoad中每一个Content-Disposition前面都有同样的字符,boundary的翻译成中文就是分界线的意思,现在意思已经很明显了吧,就是说这段“不明所以”的字符串是用来分割表单中的每个数据项的,以图中最后一个红色圈选的字符串代表本次数据表单的结尾,当服务器接受到这样的格式的请求主体信息后 ,会根据Content-Type中的boundary的值来解析对应的数据。

  2.通过代码来实现form以multipart/form-data的方式来提交数据

  编写代码过程中需要注意一下几点:

每行字符串结束后都需要以“\r\n”换新行,特别注意一下在文件流写入到请求主体后也要有“\r\n”换行;

boundary的值不能和表单数据冲突;

Content-Type后面的boundary值的前缀长度不能和Request PayLoad中的[b]boundary前缀长度一样[/b]

  代码如下:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:24219/upload.ashx");
//边界标识
string boundary = "WebKitFormBoundary" + Guid.NewGuid().ToString("N");
//开始边界
string beginBoundary = "------" + boundary;
//结束边界
string endBoundary = "------" + boundary + "--";
request.ContentType = "multipart/form-data; boundary=----" + boundary;
request.Method = "POST";

Stream requestStream = request.GetRequestStream();
//键值对
StringBuilder keyValueParam = new StringBuilder();
keyValueParam.AppendLine(beginBoundary);
keyValueParam.AppendLine("Content-Disposition: form-data; name=\"name\"");
keyValueParam.AppendLine();
keyValueParam.AppendLine("o_1bfj088gv38436s13777eo1dtn1o.jpg");
keyValueParam.AppendLine(beginBoundary);
keyValueParam.AppendLine("Content-Disposition: form-data; name=\"chunks\"");
keyValueParam.AppendLine();
keyValueParam.AppendLine("5");
byte[] keyValueByte = Encoding.UTF8.GetBytes(keyValueParam.ToString());
requestStream.Write(keyValueByte, 0, keyValueByte.Length);

//文件
StringBuilder fileParam = new StringBuilder();
fileParam.AppendLine(beginBoundary);
fileParam.AppendLine("Content-Disposition: form-data; name=\"file\"; filename=\"370x323-3.jpg\"");
fileParam.AppendLine("Content-Type: application/octet-stream");
fileParam.AppendLine();
byte[] fileParamBytes = Encoding.UTF8.GetBytes(fileParam.ToString());
requestStream.Write(fileParamBytes, 0, fileParamBytes.Length);
byte[] fileByte = File.ReadAllBytes(@"C:\Users\CSQ\Desktop\新建文件夹\370x323-2.jpg");
requestStream.Write(fileByte, 0, fileByte.Length);

//结束边界
StringBuilder endParam = new StringBuilder();
endParam.AppendLine();
endParam.AppendLine(endBoundary);//结束边界
byte[] endByte = Encoding.UTF8.GetBytes(endParam.ToString());
requestStream.Write(endByte, 0, endByte.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string result = reader.ReadToEnd();


这是用HttpWebRequest来编写的,换做HttpClient类来编写的话就更简单了,哈哈,看代码:

HttpClient client = new HttpClient();
//multipart/form-data类型的请求内容
MultipartFormDataContent httpContents = new MultipartFormDataContent();
byte[] fileByte = File.ReadAllBytes(@"C:\Users\Alan\Desktop\新建文件夹\370x323-2.jpg");
ByteArrayContent fileContent = new ByteArrayContent(fileByte);
fileContent.Headers.ContentType =new MediaTypeHeaderValue("application/octet-stream");
httpContents.Add(fileContent, "file", "370x323-2.jpg");

ByteArrayContent keyValue1 = new ByteArrayContent(Encoding.UTF8.GetBytes("o_1bfj088gv38436s13777eo1dtn1o.jpg"));
httpContents.Add(keyValue1, "name");
ByteArrayContent keyValue2 = new ByteArrayContent(Encoding.UTF8.GetBytes("5"));
httpContents.Add(keyValue2, "chunks");
var response = client.PostAsync("http://localhost:24219/upload.ashx", httpContents).Result;
response.EnsureSuccessStatusCode();


是不是很容易啊,完结!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐