我想问一个关于multipart/form-data的问题。在HTTP报头中,我发现Content-Type: multipart/form-data; boundary=???. #。
multipart/form-data
Content-Type: multipart/form-data; boundary=???
???是否可以由用户定义?还是从HTML中生成的?我是否可以定义??? = abcdefg?
???
??? = abcdefg
???是否可以由用户定义?
是的。
还是HTML提供的?
不。超文本标记语言和< em > < / em >没有有关系。阅读下面。
我是否可以将???定义为abcdefg?
abcdefg
如果需要向web服务器发送以下数据:
name = John age = 12
使用application/x-www-form-urlencoded会像这样:
application/x-www-form-urlencoded
name=John&age=12
如您所见,服务器知道参数由& &分隔。如果一个参数值需要&,那么必须对它进行编码。
&
那么,当服务器使用multipart/form-data接收HTTP请求时,它如何知道参数值的开始和结束位置呢?
使用边界,类似于&。
例如:
--XXX Content-Disposition: form-data; name="name" John --XXX Content-Disposition: form-data; name="age" 12 --XXX--
在这种情况下,边界值是XXX。您可以在Content-Type报头中指定它,以便服务器知道它接收到的数据是如何分割。
XXX
Content-Type
所以你需要:
使用一个不会出现在发送到服务器的HTTP数据中的值。
保持一致,在请求消息中处处使用相同的值。
问题实质的答案是是的。您可以为boundary参数使用任意值,只要长度小于70字节并且只包含7位# EYZ1(可打印)字符即可。
boundary
如果您使用multipart/*内容类型中的一种,则实际上是要求在Content-Type标头中指定boundary参数。否则,在HTTP请求的情况下,服务器将无法解析负载。
multipart/*
除非您绝对确定其有效负载中只使用US-ASCII字符集,否则您可能希望向每个部分添加Content-Type标头,并将charset参数设置为UTF-8。
US-ASCII
charset
UTF-8
以下是RFC2046会议的一些相关节选:
一个“charset"参数可用于指示正文文本的字符集,用于“;text"子类型,特别是包括子类型“text/plain”,这是纯文本的泛型子类型。
可以在Content-Type字段中指定的关键参数 “文本/ plain"数据是字符集。
与其他一些参数值不同,字符集参数的值不区分大小写。默认字符集是US-ASCII,在没有字符集参数的情况下必须假定它是US-ASCII。
根据Content-Transfer-Encoding字段的定义[RFC 2045],除了“&;7bit&;;8bit&;”或“&;binary&;”允许用于“multipart”类型的实体。“multipart"在任何情况下,边界分隔符和报头字段总是用7bit US-ASCII表示(尽管报头字段可以按照RFC 2047对非US-ASCII报头文本进行编码),正文部分中的数据可以按部分进行编码,每个适当的正文部分都有Content-Transfer-Encoding字段。
多部分实体的Content-Type字段需要一个参数“boundary”。然后将边界分隔符行定义为完全由两个连字符("-",十进制值45)组成的行,后面跟着Content-Type报头字段的边界参数值、可选的线性空格和终止CRLF。
边界分隔符不能出现在封装的材料中,并且不能超过70个字符(不包括两个开头的连字符)。
最后一个主体部分后面的边界分隔符行是一个明确的分隔符,表示后面没有其他主体部分。这样的分隔符行与前面的分隔符行相同,只是在边界参数值之后又添加了两个连字符。
下面是一个使用任意边界的例子:
Content-Type: multipart/form-data; boundary="yet another boundary" --yet another boundary Content-Disposition: form-data; name="foo" bar --yet another boundary Content-Disposition: form-data; name="baz" quux --yet another boundary Content-Disposition: form-data; name="feels" Content-Type: text/plain; charset=utf-8 🤷 --yet another boundary--
multipart/form-data包含边界分隔名称/值对。边界就像提交表单时传递的每个名称/值对块的标记。边界会自动添加到请求头的内容类型中。
带有enctype = " multipart /格式”属性的表单将有一个请求头Content-Type: multipart/form-data;边界——WebKit193844043-h (浏览器生成的值)。
传递的有效负载看起来像这样:
Content-Type: multipart/form-data; boundary=---WebKitFormBoundary7MA4YWxkTrZu0gW -----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=”file”; filename=”captcha” Content-Type: -----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=”action” submit -----WebKitFormBoundary7MA4YWxkTrZu0gW--
在webservice端,它以@ consumers ("multipart/form-data")的形式被使用。
注意,当使用chrome postman测试你的webservice时,你需要从下拉框中检查表单数据选项(单选按钮)和文件菜单来发送附件。将content-type显式提供为multipart/form-data会抛出错误。因为边界是丢失的,因为它通过附加边界来覆盖post man对服务器的curl请求。
看到# EYZ0
我们必须分割数据。所以,服务器知道我们发送了什么。
1示例:我们拆分数据
$email = $_POST['email']; $p_id = $_POST['pid'];
2.例如:如果我们发送JSON数据(With)内容类型Multipart/form-data,我们会得到一个与边界相关的警告
$json = file_get_contents("php://input");
使用这个
headers: { 'content-type': 'application/x-www-form-urlencoded' }
对于边界误差