如何区分空文件和丢失文件的多部分表单数据?
How to distinguish between mutli-part form data of empty file and missing file?
我在服务器端尝试区分上传空文件和未上传文件
空文件的POST正文内容为:
------WebKitFormBoundaryAYxCGhPMYcmdkdlv
Content-Disposition: form-data; name="_1"
dd
------WebKitFormBoundaryAYxCGhPMYcmdkdlv
Content-Disposition: form-data; name="_2"; filename="foo"
Content-Type: application/octet-stream
------WebKitFormBoundaryAYxCGhPMYcmdkdlv
Content-Disposition: form-data; name="_3"
Upload
------WebKitFormBoundaryAYxCGhPMYcmdkdlv--
虽然丢失的文件是
------WebKitFormBoundaryMldAHhbBqWpKPlRY
Content-Disposition: form-data; name="_1"
dd
------WebKitFormBoundaryMldAHhbBqWpKPlRY
Content-Disposition: form-data; name="_2"; filename=""
Content-Type: application/octet-stream
------WebKitFormBoundaryMldAHhbBqWpKPlRY
Content-Disposition: form-data; name="_3"
Upload
------WebKitFormBoundaryMldAHhbBqWpKPlRY--
唯一的区别是 filename=
内容一个是空的,另一个包含文件名(Firefox 和 Chromium 的行为相同)
问题:
- 是否存在浏览器不会提供
filename
(安全性或类似的东西)的任何条件?
- 实际上是valid/standard区分空文件和非设置文件的方法,请提供参考。
Content-Type: application/octet-stream
是否为标准响应,非上传文件时设置?
我希望看到一些对标准的引用,以证实或反驳我的观察结果
1。文件名
“HTML”中基于表单的文件上传的原始规范 是RFC1867
根据该规范,filename
参数
"is not required, but is strongly recommended in any case where the original filename is known"
此规范已被 RFC2388 - “从表单返回值:multipart/form-data” 取代,其中指出
The sending application MAY supply a file name ... as specified in RFC2184;
(RFC2184 继续强调它的重要性,而不是要求它)
注意这里指的是“发送应用程序”。该规范清楚地表明它与应用程序无关。
然而,对于实际实现的跨浏览器视图,Mozilla 的 FormData
的 MDN 文档对此有一些说明。
在 FormData.append()
的上下文中,其中 file/blob 是 set 但文件名未明确设置:
The default filename for Blob objects is "blob". The default filename for File objects is the file's filename.
2。空文件和无文件的区别
要回答这个问题,请务必注意 RFC2388 的 Section 5.7 - “将表单数据与原始表单相关联”
This specification provides no specific mechanism by which
multipart/form-data can be associated with the form that caused it to
be transmitted. This separation is intentional...
这个 是 在 HTML5 规范中回答的,但是详细说明了 how form data is constructed。
...if the field element is an <input>
element whose type attribute is in the File Upload state, then for each file selected in the <input>
element, append an entry to the form data set with the name as the name, the file (consisting of the name, the type, and the body) as the value, and type as the type. If there are no selected files, then append an entry to the form data set with the name as the name, the empty string as the value, and application/octet-stream as the type.
这符合您上面的观察。
查看真实世界的服务器实现如何处理此问题,以 PHP 运行时为例。
它的 API 不区分“无文件”和“空文件”——并且在任何一种情况下都会引发一个错误 UPLOAD_ERR_NO_FILE
。
因为PHP是开源的(用C写的),你可以看到那个实现here
3。 MIME 内容类型编码
这在上面的 #2 中得到了回答 - 如 HTML5 规范中所述,(来自兼容的浏览器)它将始终是 application/octet-stream
,其中表单值为空。
为了完整起见,如果 提供了 文件,RFC2388 指定:
If the contents of a file are returned via filling out a form, then the file input is identified as the appropriate media type, if known, or "application/octet-stream"
我在服务器端尝试区分上传空文件和未上传文件
空文件的POST正文内容为:
------WebKitFormBoundaryAYxCGhPMYcmdkdlv
Content-Disposition: form-data; name="_1"
dd
------WebKitFormBoundaryAYxCGhPMYcmdkdlv
Content-Disposition: form-data; name="_2"; filename="foo"
Content-Type: application/octet-stream
------WebKitFormBoundaryAYxCGhPMYcmdkdlv
Content-Disposition: form-data; name="_3"
Upload
------WebKitFormBoundaryAYxCGhPMYcmdkdlv--
虽然丢失的文件是
------WebKitFormBoundaryMldAHhbBqWpKPlRY
Content-Disposition: form-data; name="_1"
dd
------WebKitFormBoundaryMldAHhbBqWpKPlRY
Content-Disposition: form-data; name="_2"; filename=""
Content-Type: application/octet-stream
------WebKitFormBoundaryMldAHhbBqWpKPlRY
Content-Disposition: form-data; name="_3"
Upload
------WebKitFormBoundaryMldAHhbBqWpKPlRY--
唯一的区别是 filename=
内容一个是空的,另一个包含文件名(Firefox 和 Chromium 的行为相同)
问题:
- 是否存在浏览器不会提供
filename
(安全性或类似的东西)的任何条件? - 实际上是valid/standard区分空文件和非设置文件的方法,请提供参考。
Content-Type: application/octet-stream
是否为标准响应,非上传文件时设置?
我希望看到一些对标准的引用,以证实或反驳我的观察结果
1。文件名
“HTML”中基于表单的文件上传的原始规范 是RFC1867
根据该规范,filename
参数
"is not required, but is strongly recommended in any case where the original filename is known"
此规范已被 RFC2388 - “从表单返回值:multipart/form-data” 取代,其中指出
The sending application MAY supply a file name ... as specified in RFC2184;
(RFC2184 继续强调它的重要性,而不是要求它)
注意这里指的是“发送应用程序”。该规范清楚地表明它与应用程序无关。
然而,对于实际实现的跨浏览器视图,Mozilla 的 FormData
的 MDN 文档对此有一些说明。
在 FormData.append()
的上下文中,其中 file/blob 是 set 但文件名未明确设置:
The default filename for Blob objects is "blob". The default filename for File objects is the file's filename.
2。空文件和无文件的区别
要回答这个问题,请务必注意 RFC2388 的 Section 5.7 - “将表单数据与原始表单相关联”
This specification provides no specific mechanism by which multipart/form-data can be associated with the form that caused it to be transmitted. This separation is intentional...
这个 是 在 HTML5 规范中回答的,但是详细说明了 how form data is constructed。
...if the field element is an
<input>
element whose type attribute is in the File Upload state, then for each file selected in the<input>
element, append an entry to the form data set with the name as the name, the file (consisting of the name, the type, and the body) as the value, and type as the type. If there are no selected files, then append an entry to the form data set with the name as the name, the empty string as the value, and application/octet-stream as the type.
这符合您上面的观察。
查看真实世界的服务器实现如何处理此问题,以 PHP 运行时为例。
它的 API 不区分“无文件”和“空文件”——并且在任何一种情况下都会引发一个错误 UPLOAD_ERR_NO_FILE
。
因为PHP是开源的(用C写的),你可以看到那个实现here
3。 MIME 内容类型编码
这在上面的 #2 中得到了回答 - 如 HTML5 规范中所述,(来自兼容的浏览器)它将始终是 application/octet-stream
,其中表单值为空。
为了完整起见,如果 提供了 文件,RFC2388 指定:
If the contents of a file are returned via filling out a form, then the file input is identified as the appropriate media type, if known, or "application/octet-stream"