含义 ENCTYPE="multipart/form-data" 说明:

通过 http 协议上传文件 rfc1867协议概述,客户端发送内容构造。

概述                                                                                           

在最初的 http 协议中,没有上传文件方面的功能。 rfc1867为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 http server ,包括 tomcat ,已经支持此协议,可接受发送来的文件。各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。

实例                                                                                           

<form action="upFile.php" enctype="multipart/form-data" method="post">
<input name="myflie" type="file" />
<input type="submit" />

注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。

数据传输                                                                                      

格式 必须一字不差,包括最后的回车。

注意:Content-Length: 226 这里的226是红色内容的总长度(包括最后的回车)

注意这一行:

Content-Type: multipart/form-data; boundary=-----------------------------264141203718551

根据 rfc1867, multipart/form-data是必须的.---------------------------7d33a816d302b6 是分隔符,分隔多个文件、表单项。

其中7d33a816d302b6 是即时生成的字符串,用以确保整个分隔符不会在文件或表单项的内容中出现。

使用POST发送数据                                                                      

以POST方式发送数据主要是为了向服务器发送较大量的客户端的数据,它不受URL的长度限制。POST请求将数据以URL编码的形式放在HTTP正文中,字段形式为fieldname=value,用&分隔每个字段。注意所有的字段都被作为字符串处理。实际上我们要做的就是模拟浏览器POST 一个表单。以下是IE发送一个登陆表单的POST请求:

POST http://127.0.0.1/login.do HTTP/1.0
Accept: image/gif, image/jpeg, image/pjpeg, */*
Accept-Language: en-us,zh-cn;q=0.5
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Length: 28
 
username=admin&password=1234

要在MIDP应用程序中模拟浏览器发送这个POST请求,首先设置HttpConnection的请求方式为POST(PHP为curl):

// 使用POST方法
httpURLConnection.setRequestMethod("POST");

然后构造出HTTP正文:

byte[] data = "username=admin&password=1234".getBytes();

并计算正文长度,填入Content-Type和Content-Length:

httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(data.length));

然后打开OutputStream将正文写入:

OutputStream output = hc.openOutputStream();
output.write(data);

需要注意的是,数据仍需要以URL编码格式编码,由于MIDP库中没有J2SE中与之对应的URLEncoder类,因此,需要自己动手编写这个 encode()方法,可以参考java.net.URLEncoder.java的源码。剩下的便是读取服务器响应,代码与GET一致,这里就不再详述。

使用multipart/form-data发送文件                                             

如果要在MIDP客户端向服务器上传文件,我们就必须模拟一个POST multipart/form-data类型的请求,Content-Type必须是multipart/form-data。

以multipart/form-data编码的POST请求格式与application/x-www-form-urlencoded完全不同,multipart/form-data需要首先在HTTP请求头设置一个分隔符,例如ABCD:

httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=ABCD");

然后,将每个字段用“--分隔符”分隔,最后一个“--分隔符--”表示结束。例如,要上传一个title字段"Today"和一个文件C:\1.txt,HTTP正文如下:

--ABCD
Content-Disposition: form-data; name="title"
\r\n
Today
--ABCD
Content-Disposition: form-data; name="1.txt"; filename="C:\1.txt"
Content-Type: text/plain
\r\n
<这里是1.txt文件的内容>
--ABCD--
\r\n

请注意,每一行都必须以\r\n结束,包括最后一行。如果用Sniffer程序检测IE发送的POST请求,可以发现IE的分隔符类似于 ---------------------------7d4a6d158c9,这是IE产生的一个随机数,目的是防止上传文件中出现分隔符导致服务器无法正确识别文件起始位置。我们可以写一个固定的分隔符,只要足够复杂即可。

发送文件的POST代码如下:

String[] props = ... // 字段名
String[] values = ... // 字段值
byte[] file = ... // 文件内容
String BOUNDARY = "---------------------------7d4a6d158c9"; // 分隔符
StringBuffer sb = new StringBuffer();
// 发送每个字段:
for(int i=0; i
sb = sb.append("--");
sb = sb.append(BOUNDARY);
sb = sb.append("\r\n");
sb = sb.append("Content-Disposition: form-data; name=\""+ props[i] + "\"\r\n\r\n");
sb = sb.append(URLEncoder.encode(values[i]));
sb = sb.append("\r\n");
}
// 发送文件:
sb = sb.append("--");
sb = sb.append(BOUNDARY);
sb = sb.append("\r\n");
sb = sb.append("Content-Disposition: form-data; name=\"1\"; filename=\"1.txt\"\r\n");
sb = sb.append("Content-Type: application/octet-stream\r\n\r\n");
byte[] data = sb.toString().getBytes();
byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
// 设置HTTP头:
hc.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
hc.setRequestProperty("Content-Length", String.valueOf(data.length + file.length + end_data.length));
// 输出:
output = hc.openOutputStream();
output.write(data);
output.write(file);
output.write(end_data);
// 读取服务器响应:
// TODO...

参考:http://hi.baidu.com/ycvwvuykhkbadmd/item/e441cc0e36fcd6dd73e676bd

转载请注明出处:http://www.cnblogs.com/yydcdut/p/3736667.html

上传文件multipart form-data boundary 说明的更多相关文章

  1. Html Ajax上传文件,form表单下载文件

    Html中的代码: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type&quo ...

  2. http 协议上传文件multipart form-data boundary 说明--转载

    原文地址:http://xixinfei.iteye.com/blog/2002017 含义 ENCTYPE="multipart/form-data" 说明: 通过 http 协 ...

  3. httprunner上传文件multipart/form-data

    Content-Type = multipart/form-data#上传文件 Rquest Payload ------WebKitFormBoundarymAyGmnyhpf3UBdec    C ...

  4. js 上传文件模拟Form 表单

    使用FormData对象 在本文章中 创建一个FormData对象 使用HTML表单来初始化一个FormData对象 使用FormData对象发送文件 利用FormData对象,你可以使用一系列的键值 ...

  5. 上传文件时form表单需要添加的属性

    enctype="multipart/form-data"

  6. ajax提交可以上传文件的form表单

    var formData = new FormData($( "#fm")[0]);       $.ajax({            url: 'webnavigationcw ...

  7. Django框架 之 Form表单和Ajax上传文件

    Django框架 之 Form表单和Ajax上传文件 浏览目录 Form表单上传文件 Ajax上传文件 伪造Ajax上传文件 Form表单上传文件 html 1 2 3 4 5 6 7 <h3& ...

  8. vue form表单上传文件

    <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js">< ...

  9. Django学习——ajax发送其他请求、上传文件(ajax和form两种方式)、ajax上传json格式、 Django内置序列化(了解)、分页器的使用

    1 ajax发送其他请求 1 写在form表单 submit和button会触发提交 <form action=""> </form> 注释 2 使用inp ...

随机推荐

  1. web服务端安全之SQL注入攻击

    一.SQL注入攻击的原理攻击者在HTTP请求中,注入恶意的SQL代码,并在服务端执行.比如用户登录,输入用户名camille,密码 ' or '1'='1 ,如果此时使用参数构造的方式,就会出现 ' ...

  2. string rune byte 的关系

    在Go当中 string底层是用byte数组存的,并且是不可以改变的. 例如 s:="Go编程" fmt.Println(len(s)) 输出结果应该是8因为中文字符是用3个字节存 ...

  3. Codeforces Round #360 (Div. 2) B. Lovely Palindromes 水题

    B. Lovely Palindromes 题目连接: http://www.codeforces.com/contest/688/problem/B Description Pari has a f ...

  4. Codeforces Round #297 (Div. 2)D. Arthur and Walls 暴力搜索

    Codeforces Round #297 (Div. 2)D. Arthur and Walls Time Limit: 2 Sec  Memory Limit: 512 MBSubmit: xxx ...

  5. C#高级编程9-第7章 运算符和类型强制转换

    运算符和类型强制转换 1.运算符 运算符的简化操作 条件运算符: if-else的简化操作,也称三元运算符.如果条件为真,返回一个值,为假返回另外一个值. condition?true_value:f ...

  6. Jmeter学习之— 参数化、关联、断言、数据库的操作

    一. Jmeter参数化1. 文件参数化解释:创建测试数据,将数据写入TXT文件文件中,然后Jmeter从文件中读取数据.例如用户注册操作:1. 首先在Jmeter下创建一个线程组,如下图: 2. 然 ...

  7. C++各大名库

    C++各大名库的介绍之C++标准库 标准库中提供了C++程序的基本设施.虽然C++标准库随着C++标准折腾了许多年,直到标准的出台才正式定型,但是在标准库的实现上却很令人欣慰得看到多种实现,并且已被实 ...

  8. oracle_创建表空间、用户、授权等步骤

    --创建表空间(在system用户下才可以创建) //connect system/manager as sysdba:切换到system用户 create tablespace tz datafil ...

  9. Windows Server 2016 Essentials试用

    下载地址: Windows Server 2016 Essentials (x64) SHA-1:        6E1D1880873157ADCEF3D74363308A95DC89103D ed ...

  10. web语义化,从松散到实战

    GitHub:http://liu12fei08fei.github.io/html/4semantic.html web语义化,从松散到实战 在这篇文章之前,我放弃了很多次,写关于语义化方面的文章: ...