[13-Dec-2022 17:56:46 Asia/Shanghai] PHP Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0
最近在服务器中发现大量的Missing boundary缺少边界分隔符的警告日志信息。研究了半天,在此做个总结说明。
了解multipart/form-data
enctype:规定了form表单在发送到服务器时候编码方式,它有如下的三个值。
application/x-www-form-urlencoded:默认的编码方式。但是在用文本的传输和MP3等大型文件的时候,使用这种编码就显得 效率低下。
multipart/form-data:指定传输数据为二进制类型,比如图片、mp3、文件。
text/plain:纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。
根据上述说明,我们可以了解到multipart/form-data是用于传输二进制文件流的,可简单理解为上传文件的时候的时候需要指定的Content-type类型。
认识boundary
boundary属性 根据RFC 1867定义,我们需要选择一段数据作为“分割边界”( boundary属性),这个“边界数据”不能在内容其他地方出现,一般来说使用一段从概率上说“几乎不可能”的数据即可。 不同浏览器的实现不同,每次post浏览器都会生成一个随机的30-40位长度的随机字符串,浏览器一般不会遍历这次post的所有数据找到一个不可能出现在数据中的字符串,这样代价过大,一般都是随机生成。 Rfc1867这样说明{A boundary is selected that does not occur in any of the data. (This selection is sometimes done probabilisticly.)}。
根据上述说明,我们可以意识到boundary是由浏览器生成的一段随机字符串,作为浏览器请求的边界分隔符。
multipart/form-data与boundary关系
multipart/form-data是基于post方法来传递数据的,并且其请求内容格式为Content-Type: multipart/form-data,用来指定请求内容的数据编码格式。另外,该格式会生成一个boundary字符串来分割请求头与请求体的,具体的是以一个boundary=${boundary}来进行分割。
如下所示,请求的header头信息中,需要指定Content-Type: multipart/form-data;boundary={boundary边界字符串}
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW完整http请求报文
POST /hello/world/1798 HTTP/1.1 Host: beta.1798dev.com Cookie: 17comuuid=39dea847-deb3-0555-f46d-3790498123cb; PHPSESSID=75de2a5920eedd9cccc98fa2b00ef8e3; searchEngines=1; user_current_city=beijing Content-Length: 391 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW ----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="code" df854d9edaf308e2d23d7d5d3b68b3c3NW ----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="client_id" y3kbdTP1Xr1loiycavmg2Y95vdpZ4w9B ----WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="sk" paIfwQYYC2AMYfv5aUwG3wyT2XykNMyj ----WebKitFormBoundary7MA4YWxkTrZu0gW从上面可以清晰的看到boundary边界分隔符字符串----WebKitFormBoundary7MA4YWxkTrZu0gW在传输报文中的应用。
Missing boundary如何产生?
很明显是请求header头信息中Content-type指定了只指定了multipart/form-data,没有指定boundary分割字符串。
演示复现Missing boundary in multipart/form-data
使用postman按照下面格式构造请求信息