【问题标题】:How to distinguish between mutli-part form data of empty file and missing file?如何区分空文件和丢失文件的多部分表单数据?
【发布时间】:2021-04-27 18:09:36
【问题描述】:

我尝试在服务器端区分上传空文件和未上传文件

空文件的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 的行为相同)

问题:

  1. 是否存在浏览器不提供filename(安全或类似的东西)的条件?
  2. 区分空文件和非设置文件是否真正有效/标准的方法,请提供参考。
  3. Content-Type: application/octet-stream是标准响应,未上传文件时设置?

我希望看到一些可以证实或反驳我的观察的标准参考

【问题讨论】:

    标签: http file-upload multipartform-data


    【解决方案1】:

    1。文件名

    “HTML 中基于表单的文件上传”的原始规范是RFC1867

    根据该规范,filename 参数

    “不是必需的,但在原始文件名已知的任何情况下都强烈推荐”

    此规范已被 RFC2388 取代 - “从表单返回值:multipart/form-data”,其中指出

    发送应用程序可以提供一个文件名...如RFC2184 中指定的那样;

    (RFC2184 继续强调其重要性,但没有要求)

    请注意,它指的是“发送应用程序”。该规范清楚地表明它与应用程序无关。 然而,对于实际实现的跨浏览器视图,Mozilla 的 FormData 的 MDN 文档对此有所了解。 在FormData.append() 的上下文中,其中文件/blob 已设置,但文件名未明确设置:

    Blob 对象的默认文件名是“blob”。 File 对象的默认文件名是文件的文件名。

    2。空文件和无文件的区别

    要回答这个问题,请务必注意 RFC2388 的 Section 5.7 - “将表单数据与原始表单相关联”

    本规范没有提供具体的机制 multipart/form-data 可以与导致它的表单相关联 被传送。这种分离是故意的……

    这个在 HTML5 规范中得到了回答,其中详细说明了how form data is constructed

    ...如果 field 元素是 <input> 元素,其 type 属性处于文件上传状态,则对于在 <input> 元素中选择的每个文件,使用 name 作为名称,文件(由名称、类型和正文组成)作为值,type 作为类型。 如果没有选定的文件,则在表单数据集中附加一个条目,名称为名称,空字符串为值,类型为 application/octet-stream。

    这与您上面的观察结果相符。

    看看现实世界的服务器实现如何处理这个问题,以 PHP 运行时为例。 它的 API 不区分“无文件”和“空文件” - 在任何一种情况下都会引发单个错误 UPLOAD_ERR_NO_FILE

    由于 PHP 是开源的(用 C 编写),您可以看到实现 here

    3。 MIME 内容类型编码

    这在上面的#2 中得到了回答——正如 HTML5 规范中详述的那样,(来自兼容的浏览器)它总是application/octet-stream,其中表单值为空。

    为了完整起见,如果提供了一个文件,RFC2388 指定:

    如果文件的内容是通过填写表格返回的,则文件输入被标识为适当的媒体类型(如果已知)或“application/octet-stream”

    【讨论】:

    • 哇 - 很好的答案 - 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多