原文链接:http://blog.csdn.net/five3/article/details/7181521

首先来了解什么是multipart/form-data请求:

根据http/1.1 rfc 2616的协议规定,我们的请求方式只有OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE等,那为为何我们还会有multipart/form-data请求之说呢?这就要从头来说了。

http协议大家都知道是规定了以ASCII码传输,建立在tcp、ip协议之上的应用层规范,规范内容把http请求分为3个部门:状态行,请求头,请求体。所有的方法、实现都是围绕如何运用和组织这三部分来完成的。换句话来说就是万变不离其中,只要我们了解了http请求的组成部分后,自然就可以应变任何实际工作中的需求和问题了。

关于状态行,请求头,请求体等三部分的具体内容,大家可以参考官方的协议文档http://www.faqs.org/rfcs/rfc2616.html,这里主要分析multipart/form-data请求具体是怎么一回事。

既然http协议本身的原始方法不支持multipart/form-data请求,那这个请求自然就是由这些原始的方法演变而来的,具体如何演变且看下文:

1、multipart/form-data的基础方法是post,也就是说是由post方法来组合实现的

2、multipart/form-data与post方法的不同之处:请求头,请求体。

3、multipart/form-data的请求头必须包含一个特殊的头信息:Content-Type,且其值也必须规定为multipart/form-data,同时还需要规定一个内容分割符用于分割请求体中的多个post的内容,如文件内容和文本内容自然需要分割开来,不然接收方就无法正常解析和还原这个文件了。具体的头信息如下:

//其中${bound} 是一个占位符,代表我们规定的分割符,可以自己任意规定,但为了避免和正常文本重复了,尽量要使用复杂一点的内容。如:--------------------56423498738365

4、multipart/form-data的请求体也是一个字符串,不过和post的请求体不同的是它的构造方式,post是简单的name=value值连接,而multipart/form-data则是添加了分隔符等内容的构造体。具体格式如下:

其中${bound}为之前头信息中的分割符,如果头信息中规定为123,那么这里也要为123,;可以很容易看出,这个请求体是多个相同的部分组成的:每一个部分都是以--加分隔符开始的,然后是该部分内容的描述信息,然后一个回车,然后是描述信息的具体内容;如果传送的内容是一个文件的话,那么还会包含文件名信息,以及文件内容的类型。上面的第二个小部分其实是一个文件体的结构,最后会以--分割符--结尾,表示请求体结束。

综上,可以知道要发送一个multipart/form-data的请求,其实任何支持post请求的工具或语言都可以支持,只是自己要稍微包装一下便可。

参考资料:

百度百科: http://baike.baidu.com/view/9472.htm

http1.1协议规范: http://www.faqs.org/rfcs/rfc2616.html

分析工具:httpAnalyzer

当然,附上C#源码,应该很轻松就可以转Java

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Msf.Engine.Network.NetworkTool
{
public sealed class MultipartFormData : IDisposable
{
public const string Boundary = "--the_great_maoshu--"; public static string ContentType
{
get { return "multipart/form-data; boundary=" + Boundary; }
} private MemoryStream _stream;
public MemoryStream Stream
{
get { return _stream ?? (_stream = new MemoryStream()); }
} public MultipartFormData()
{
} public void AddContent(string name, string value)
{
var sp = string.Format("--{0}\r\n", Boundary);
sp += string.Format(
"Content-Disposition: form-data; name=\"{0}\"; \r\n\r\n{1}",
name,
value);
var data = Encoding.UTF8.GetBytes(sp);
Stream.Write(data, 0, data.Length);
} public void AddContent(string name, string fileName, byte[] fileData)
{
var sp = string.Format("--{0}\r\n", Boundary);
sp += string.Format(
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n",
name,
fileName);
var data = Encoding.UTF8.GetBytes(sp);
Stream.Write(data, 0, data.Length);
Stream.Write(fileData, 0, fileData.Length);
data = Encoding.UTF8.GetBytes("\r\n");
Stream.Write(data, 0, data.Length);
} public byte[] GetPostData()
{
var sp = string.Format("--{0}--\r\n", Boundary);
var data = Encoding.UTF8.GetBytes(sp);
Stream.Write(data, 0, data.Length); Stream.Position = 0;
return Stream.ToArray();
} public void Dispose()
{
if (_stream != null) _stream.Dispose();
_stream = null;
}
}
}

【转】HTTP协议之multipart/form-data请求分析的更多相关文章

  1. fetch发送Form Data请求并携带cookie

    今天我们来说说如何fetch发送Form Data请求并携带cookie,直接进入正题好吧,别问我今天为啥不在开始吹两句了,累到一句牛逼不想吹...... 步骤1: 设置头部,"Conten ...

  2. HTTP协议详解之http请求分析

    当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无论Web技术在未来如何发展,理解Web程序之间通信的基本协议相当重要, 因为它让我们理解了We ...

  3. (转载)http协议的Request Payload 和 Form Data 的区别

    我正在开发的项目前端和后端是完全独立的,通过配置 webpack 的 proxy 将前端请求跨域代理到后台服务.昨天发现,我前端执行 post 请求,后台 springmvc 的 @RequestMa ...

  4. html5 file upload and form data by ajax

    html5 file upload and form data by ajax 最近接了一个小活,在短时间内实现一个活动报名页面,其中遇到了文件上传. 我预期的效果是一次ajax post请求,然后在 ...

  5. Sending forms through JavaScript[form提交 form data]

    https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript As in the ...

  6. Request Payload 和 Form Data 的区别

    概述 我正在开发的项目前端和后端是完全独立的,通过配置 webpack 的 proxy 将前端请求跨域代理到后台服务.昨天发现,我前端执行 post 请求,后台 springmvc 的 @Reques ...

  7. HTTP请求中的form data和request payload的区别

    HTML <form> 标签的 enctype 属性 在下面的例子中,表单数据会在未编码的情况下进行发送: <form action="form_action.asp&qu ...

  8. AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式

    转载:http://blog.csdn.net/mhmyqn/article/details/25561535 HTTP请求中,如果是get请求,那么表单参数以name=value&name1 ...

  9. AJAX POST请求中參数以form data和request payload形式在servlet中的获取方式

    HTTP请求中,假设是get请求,那么表单參数以name=value&name1=value1的形式附到url的后面,假设是post请求,那么表单參数是在请求体中,也是以name=value& ...

  10. [转]AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式

    转载至 http://blog.csdn.net/mhmyqn/article/details/25561535 最近在写接收第三方的json数据, 因为对java不熟悉,有时候能通过request能 ...

随机推荐

  1. 跨浏览器的javascript事件的封装

    一,跨浏览器的事件处理程序 1,DOM0级处理事件 将一个函数赋值给一个事件处理程序属性. 事件流:冒泡阶段. 使用: 为元素增加事件: var btn = document.getElementBy ...

  2. ARM中几个典型的汇编指令解析

    启动嵌入式设备时,遇到了一些汇编,做个笔记,免得以后忘记了. 一句汇编语句如下所指示: __asm ( ".syntax unified\n" ".thumb\n&quo ...

  3. centos7的ssh服务连接

    ---恢复内容开始--- SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SSH 为建立在应用层基础上的安全协议.SSH 是 ...

  4. 顺序栈,链栈,队列java实现

    顺序栈 /** * 顺序栈 * */ public class SqStack { //栈的大小 private int maxSize; //栈顶指针 private int top; privat ...

  5. [视频]K8飞刀 S2-020 exploit getshell 动画教程

    [视频]K8飞刀 S2-020 exploit getshell 动画教程 链接:https://pan.baidu.com/s/1G5x7Dcu6pzHz6ZfSCDDmKA 提取码:05kw

  6. C#7.0--引用返回值和引用局部变量

    一.在C#7.0以上版本中,方法的返回值可以通过关键字ref指定为返回变量的引用(而不是值)给调用方,这称为引用返回值(Reference Return Value,或ref returns): 1. ...

  7. Linux命令yum和rpm

    yum命令使用 可以简化软件安装命令 yum可以做软件的 1自动安装,安装软件的时候会自动安装需要的依赖 yum install 软件名如安装epel源yum install epel-release ...

  8. PostgreSQL 数据类型

    数值类型 数值类型由两个字节,4字节和8字节的整数,4字节和8字节的浮点数和可选精度的小数.下表列出了可用的类型. www.yiibai.com Name Storage Size Descripti ...

  9. Docker入门记1

    Docker是一个部署容器技术,它出现的目的主要解决开发人员在本机开发的时候安装的各类类库等一系列运行程序的包啊库啊,然后把这些引用的第三方类库和操作系统需要的配置打包起来,形成一个原子环境,然后部署 ...

  10. apache tomcat搭建负载均衡(实现集群中的session同步)

    原理:tomcat 做个WEB服务器有它的局限性,处理能力低,效率低.承受并发小(1000左右).但目前有不少网站或者页面是JSP的.并采用了tomcat做为WEB,因此只能在此基础上调优. 目前采取 ...