HTTP协议之multipart/form-data请求分析
来源:互联网 发布:vs.php for vs2015 编辑:程序博客网 时间:2024/06/13 00:10
问题引出
在解决文件上传附带参数的时候,发现当form中添加enctype:"multipart/form-data",后台用request.getParameter(“XXX”)获取不到数据
原因分析:
1.get方式
get方式提交的话,表单项都保存在http header中,格式是
http://localhost:8080/hello.do?name1=value1&name2=value2这样的字符串。server端通过request.getParameter是可以取到值的。
2.post方式(enctype为缺省的application/x-www-form-urlencoded)
表单数据都保存在http的正文部分,格式类似于下面这样:用request.getParameter是可以取到数据的
name1=value1&name2=value2
3.post方式(enctype为multipart/form-data,多用于文件上传,对于只想传value的做法,显然使用application/json或者text/plain会好很多。可以把数据放到form的header或者body中,在后台使用相应的方法得到具体值)
表单数据都保存在http的正文部分,各个表单项之间用boundary隔开。格式类似于下面这样:用request.getParameter()是取不到数据的,这时需要通过request.getInputStream来取数据,不过取到的是个InputStream,所以无法直接获取指定的表单项(需要自己对取到的流进行解析,才能得到表单项以及上传的文件内容等信息)。这种需求属于比较共通的功能,所以有很多开源的组件可以直接利用。比如:apache的fileupload组件,smartupload等。通过这些开源的upload组件提供的API,就可以直接从request中取得指定的表单项了。
什么是multipart/form-data请求:
1、multipart/form-data的基础方法是post,也就是说是由post方法来组合实现的
2、multipart/form-data与post方法的不同之处:请求头,请求体。
3、multipart/form-data的请求头必须包含一个特殊的头信息:Content-Type,且其值也必须规定为multipart/form-data,同时还需要规定一个内容分割符用于分割请求体中的多个post的内容,如文件内容和文本内容自然需要分割开来,不然接收方就无法正常解析和还原这个文件了。具体的头信息如下:
[html] viewplain copy
1. Content-Type: multipart/form-data; boundary=${bound}
//其中${bound}是一个占位符,代表我们规定的分割符,可以自己任意规定,但为了避免和正常文本重复了,尽量要使用复杂一点的内容。如:--------------------56423498738365
4、multipart/form-data的请求体也是一个字符串,不过和post的请求体不同的是它的构造方式,post是简单的name=value值连接,而multipart/form-data则是添加了分隔符等内容的构造体。具体格式如下:
--${bound}
Content-Disposition: form-data; name="Filename"
HTTP.pdf
--${bound}
Content-Disposition: form-data; name="file000"; filename="HTTP协议详解.pdf"
Content-Type: application/octet-stream
%PDF-1.5
file content
%%EOF
--${bound}
Content-Disposition: form-data; name="Upload"
Submit Query
--${bound}--
其中${bound}为之前头信息中的分割符,如果头信息中规定为123,那么这里也要为123,;可以很容易看出,这个请求体是多个相同的部分组成的:每一个部分都是以--加分隔符开始的,然后是该部分内容的描述信息,然后一个回车,然后是描述信息的具体内容;如果传送的内容是一个文件的话,那么还会包含文件名信息,以及文件内容的类型。上面的第二个小部分其实是一个文件体的结构,最后会以--分割符--结尾,表示请求体结束。
综上,可以知道要发送一个multipart/form-data的请求,其实任何支持post请求的工具或语言都可以支持,只是自己要稍微包装一下便可。
form表单设置enctype="multipart/form-data"后获取参数
方案一:js修改上传路径
[html] viewplain copy
1. <form id="upload" name="upload" action="fileftp.jsp" method="post" ENCTYPE="multipart/form-data">
2. <input type="hidden" name="otherName" id="otherName" value="abcdefg"/>
3. <td nowrap>
4. <input type="file" id="file1" name="file1" value="" size="40" class="sbttn"/>
5. <input type="submit" value="上传" class="sbttn"/>
6. </td>
7. </form>
当表单提交到fileftp.jsp后,是无法使用request.getParameter("otherName")获得到abcdefg的值的。但是可以获得到file1的文件。
这里使用JS在表单提交的时候将参数拼接在表单action地址的后面。代码像这样的:
[javascript] viewplain copy
1. <script language="javascript">
2. function formSubmit(){
3. var action="fileftp.jsp";
4. action+="?otherName="+document.upload.otherName.value;
5. document.upload.action=action;
6. document.upload.submit();
7. }
8. </script>
- HTTP multipart/form-data 请求协议分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- HTTP协议之multipart/form-data请求分析
- DNS服务-笔记
- 传智播客-Java学习笔记day14
- Swift 学习笔记01-字符串及运算符
- hdu 2819 求最小顶点覆盖数
- Centos 7配置LAMP
- HTTP协议之multipart/form-data请求分析
- QtWebkits如何向QtWebEngine过渡
- 线性矩阵到底是什么
- 卸载Oracle12c方法
- Maven环境配置和idea创建maven项目
- 分表+分区
- 编程笔试题
- nginx 403 Forbidden 错误怎么解决?
- POJ2955 Brackets(区间DP)