资讯专栏INFORMATION COLUMN

multipart/form-data 格式的http请求,以及lua构造实现

cncoder / 1943人阅读

摘要:图片二进制数据以上是截取了一个典型的格式的请求的部分,我们逐行来分析。首先第一行,很简单,指定了值,表明了这条请求是类型的。

大多数前端工程师对于这个multipart/form-data并不陌生,当我们需要发送二进制数据如图片时,通常会用到这个玩意儿~我们用form表单提交数据时,会指定form元素的enctype属性值为multipart/form-data,又或者使用html5新对象Formdata,我们用ajax发送数据时会指定content-type为multipart/form-data.

multipart/form-data数据格式

我们来看看这个multipart/form-data究竟有什么特别之处。


Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Host: w.sohu.com
 
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="desc"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
 
[......][......][......][......]...........................
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="pic"; filename="photo.jpg"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
 
[图片二进制数据]
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--


以上是截取了一个典型的multipart/form-data格式的http请求的部分,我们逐行来分析。

首先第一行,很简单,指定了Content-Type值,表明了这条http请求是multipart/form-data类型的。
细心的你可能发现了有一个名为boundary的玩意儿,它的值是一串看起来毫无规律的字符串。
先不急,我们来看一下具体的数据~分析数据我们可以看到刚才提到的boundary值在数据体中重复出现了多次。没错,这个boundary就是用来分割不同数据块的,当你提交这个请求后,后台会根据你在content-type中指定的boundary值来解析你的数据。

Content-Disposition用来表明该数据是表单数据,name用来说明这块数据块的名称,当是二进制数据时,你还需指定filename,即文件名。

multipart/form-data对数据格式要求非常严格,换行时必须使用
,而不是
,分隔符boundary在使用时,必须加上"--",即--boundary
,数据体完结后,用--boundary--表明结束

稍微介绍了multipart/form-data的相关知识,我们现在进入重点:使用Lua来构造multipart/form-data格式的数据,并与webserver交互(在这里使用php)

我们需要使用到lua的一个模块,socket.http(安装引用不在本文讨论范围,请读者自行学习)

    local resbody = {}
    local reqfile= io.open(your-file-path)    
    local file_attr = lfs.attributes(your-file-path)
    local size = file_attr.size  --获取文件大小
    local  body, code, headers, status = http.request {
            method = "POST",
            url ="http://xxxx/upload.php",
            headers = {
                ["Content-Type"] =  "multipart/form-data",
                ["Content-Length"] = size
            },
            source = ltn12.source.file(reqfile),
            sink = ltn12.sink.table(respbody)
        }

注意,以上代码是我从stackoverflow上看到类似的,提问者自称能成功发送,但是这样的方式,在php里只能用file_get_contents( php://input )来获取原始数据流,但是$_POST和$_FILES数组拿不到你的数据,这显然不是我们想要的。


构造数据:
    local respbody = {}
    local _file = [[--abcd]].."
"..[[Content-Disposition: form-data; name="myfile"; filename="1.jpg"]].."
"..[[Content-Type: image/jpeg]].."

"
    local _table1 = "
"..[[--abcd]].."
"..[[Content-Disposition: form-data; name="type";]].."

"..[[0]]
    local _table2 = "
"..[[--abcd]].."
"..[[Content-Disposition: form-data; name="themeName";]].."

"..[[1482753000731]]
    local _end ="
"..[[--abcd--]].."
"
    local reqfile= io.open(your-file-path)
    local file_attr = lfs.attributes(your-file-path)
    local size = file_attr.size
    local  body, code, headers, status = http.request {
        method = "POST",
        url = "http://xxxx/upload.php",
        headers = {
            ["Content-Type"] =  "multipart/form-data;boundary=abcd",
            ["Content-Length"] = size+#_file+#_table1+#_table2+#_end
        },
        source = ltn12.source.cat(ltn12.source.string(_file),ltn12.source.file(reqfile),ltn12.source.string(_table1),ltn12.source.string(_table2),ltn12.source.string(_end)),
        sink = ltn12.sink.table(respbody)
    }

注意:我们这里进行了字符串块的拼接,ltn12.source.string()只能接受字符串块,这里的拼接过程中,换行符
需要特别注意。

以上就是使用Lua构造multipar/form-data格式数据,并发送请求的全部内容,感谢阅读。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/50322.html

相关文章

  • multipart/form-data 格式http请求以及lua构造实现

    摘要:图片二进制数据以上是截取了一个典型的格式的请求的部分,我们逐行来分析。首先第一行,很简单,指定了值,表明了这条请求是类型的。 大多数前端工程师对于这个multipart/form-data并不陌生,当我们需要发送二进制数据如图片时,通常会用到这个玩意儿~我们用form表单提交数据时,会指定form元素的enctype属性值为multipart/form-data,又或者使用html5新...

    Wuv1Up 评论0 收藏0
  • lua web快速开发指南(4) - 详细了解httpd库作用

    摘要:库是基于协议实现而来内置了高性能的协议解析器与解析库库默认情况下就能工作的很好但是在一些需求较为极端的场景还是需要微调一下参数常用的内置方法介绍设置每个连接到最大空闲连接等待时间超过这个数值将主动断开连接默认值为秒设置的最大长度超过这个值将 httpd库是基于HTTP 1.1协议实现而来, 内置了高性能的http协议解析器与urldecode解析库. httpd库默认情况下就能工作的很...

    ChristmasBoy 评论0 收藏0
  • AFNetWorking源码之AFHTTPSessionManager

    摘要:协议规定提交的数据必须放在消息主体中,但协议并没有规定数据必须使用什么编码方式。上传文件的数据部分使用二进制数据拼接。上边界部分和下边界部分的字符串最后都要转换成二进制数据和文件部分的二进制数据拼接在一起作为请求体发送给服务器。 1 概述 AFHTTPSessionManager是AFURLSessionManager的子类。我们可以通过这个类做HTTP请求。其实整个AFHTTPSes...

    stefan 评论0 收藏0
  • GET,POST与后端接口详记

    摘要:如,是类的传输方式,与没有实质区别。是测试服务器的该资源情况,不返回实体的主体部分。请求可以获取回服务器接收到的该请求的原始报文,从而判断路径中的代理和防火墙是否对该条请求进行修改。为了获取信息且不需要传大量条件信息的接口。 前言 HTTP通信的7种方式 在HTTP通信中主要分为GET和POST。如PUT,DELETE是类POST的传输方式,与POST没有实质区别。OPTION是查看服...

    miguel.jiang 评论0 收藏0
  • GET,POST与后端接口详记

    摘要:如,是类的传输方式,与没有实质区别。是测试服务器的该资源情况,不返回实体的主体部分。请求可以获取回服务器接收到的该请求的原始报文,从而判断路径中的代理和防火墙是否对该条请求进行修改。为了获取信息且不需要传大量条件信息的接口。 前言 HTTP通信的7种方式 在HTTP通信中主要分为GET和POST。如PUT,DELETE是类POST的传输方式,与POST没有实质区别。OPTION是查看服...

    jasperyang 评论0 收藏0

发表评论

0条评论

cncoder

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<