首页 编程 正文
1473

multipart/form-data类型请求体的手动拼装

HTTP协议规定的POST方法是客户端向服务端写入数据的操作,其请求体就是待写入的数据段。multipart/form-data是对请求体的格式进行规范化的定义,也有点类似于协议的味道。就比如application/json,它告之服务端,此次的请求体格式是一串JSON数据。还有我们熟知的application/x-www-form-urlencoded,它告之服务端请求体的格式是查询字符串形式的数据。那么multipart/form-data又是一种什么样的格式呢?其实就是,它是将请求体数据按某个分隔符分割成好几段数据,并为每一段数据标识了一个名称,从浏览器的实现来看,就是form表单里面那些input控件的字段名。所以这里有几个关键的地方:

第一,设置请求头的Content-Type,以明确请求体类型,并声明数据段的分隔符是什么。
即:Content-Type: multipart/form-data; boundary=abcdefgh
boundary的值就是定义分割符,它就是一个普通的ASCII字符串,可以随意定义,但是一般要满足:a、足够的长度。b、足够的随机性。
这两点是为了保证分割符不会污染数据本身。(分割符和数据实质上来说是混在一起的一段数据)。

第二、数据分段的规则。
--${boundary} 用来分隔每个数据段。
--${boundary}-- 用来表示整个请求体结束。
例如:
--9a8f7e25b7f276955e4f41094c87281db5db920e1
Content-Disposition: form-data; name="fieldname"

PHP is the best language in the world.
--9a8f7e25b7f276955e4f41094c87281db5db920e1
Content-Disposition: form-data; name="file"; filename="image.jpg"

${二进制数据}
--9a8f7e25b7f276955e4f41094c87281db5db920e1--
上面这段请求体数据就是一个典型的form表单文件上传的例子。注意请求体中每行数据的换行符是 "\r\n"

通过上面的分析,其实要自己来包装一个form表单请求也是不难的,下面就用javascript简单地展示一下示例代码:
function wrapbody(){
    var boundary = '--9a8f7e25b7f276955e4f41094c87281db5db920e1', 
    end_boundary = boundary + '--', end_line = '\r\n';
    var body = '';
    body += boundary + end_line;
    body += 'Content-Disposition: form-data; name="fieldname"' + end_line;
    body += end_line;
    body += 'PHP is the best language in the world.' + end_line;
    body += boundary + end_line;
    body += 'Content-Disposition: form-data; name="file"; filename="image.jpg"' + end_line;
    body += end_line;
    body += fs.readFileSync('/root/demo/image.jpg') + end_line;
    body += end_boundary;
    return body;
}



正在加载评论...