多部分/表单数据的边界是什么?

我想问一个关于multipart/form-data的问题。在HTTP报头中,我发现Content-Type: multipart/form-data; boundary=???. #。

???是否可以由用户定义?还是从HTML中生成的?我是否可以定义??? = abcdefg?

544731 次浏览

???是否可以由用户定义?

是的。

还是HTML提供的?

不。超文本标记语言< em > < / em >没有有关系。阅读下面。

我是否可以将???定义为abcdefg?

是的。

如果需要向web服务器发送以下数据:

name = John
age = 12

使用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报头中指定它,以便服务器知道它接收到的数据是如何分割

所以你需要:

  • 使用一个不会出现在发送到服务器的HTTP数据中的值。

  • 保持一致,在请求消息中处处使用相同的值。

问题实质的答案是是的您可以为boundary参数使用任意值,只要长度小于70字节并且只包含7位# EYZ1(可打印)字符即可。

如果您使用multipart/*内容类型中的一种,则实际上是要求Content-Type标头中指定boundary参数。否则,在HTTP请求的情况下,服务器将无法解析负载。

除非您绝对确定其有效负载中只使用US-ASCII字符集,否则您可能希望向每个部分添加Content-Type标头,并将charset参数设置为UTF-8

以下是RFC2046会议的一些相关节选:

  • < p > 4.1。文本媒体类型

    一个“charset"参数可用于指示正文文本的字符集,用于“;text"子类型,特别是包括子类型“text/plain”,这是纯文本的泛型子类型。

  • < p > 4.1.2。字符集参数

    可以在Content-Type字段中指定的关键参数 “文本/ plain"数据是字符集。

    与其他一些参数值不同,字符集参数的值不区分大小写。默认字符集是US-ASCII,在没有字符集参数的情况下必须假定它是US-ASCII。

  • < p > 5.1。多部分媒体类型

    根据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'
}

对于边界误差