Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC 1867 文件上传 #1

Open
ryancui92 opened this issue Jul 16, 2017 · 0 comments
Open

RFC 1867 文件上传 #1

ryancui92 opened this issue Jul 16, 2017 · 0 comments

Comments

@ryancui92
Copy link
Owner

HTML FORM 的调整

1867 首先对 HTML 的 form 元素进行了两处改变:

  1. input 元素的 type 属性增加一个 file 属性
  2. input 元素增加一个 accept 属性,表示允许的文件类型

当使用 form 进行文件上传时,enctype 应设为 multipart/form-data。此后当对 form 进行 submit 时,会使用 form-data 的格式发送 HTTP 请求。

要注意的是,当 form 元素中含有 input type=file 而没有设置 enctype 时,行为是未定义的。

If a form contains <INPUT TYPE=file> elements but does not contain an ENCTYPE in the enclosing <FORM>, the behavior is not specified.

建议的实现

浏览器应该如何实现 type="file"input 元素

RFC 中提到需要一个显示文件名的区域和一个用于选择文件的按钮。当 accept 属性存在时,文件选择器还需要约束可以选择文件类型。

使用效率更高的 multipart/form-data 而不是 application/x-www-form-urlencoded

The encoding type application/x-www-form-urlencoded is inefficient for sending large quantities of binary data or text containing non-ASCII characters.

额外的功能

加密与解密

multipart/form-data 不负责加解密。而有部分链路层协议会在链路层进行自动的加密与解密,有此需求的可以自行实现(或使用 HTTPS)。

延迟文件上传

有时候文件上传不一定需要,服务器可能需要验证其余字段是否有效,然后才允许进行文件的上传。对此需求 RFC 的建议是拆分成多个 form 进行提交,将文件上传的协议保持简单。

使 input 元素过重?

对使用 input 元素实现文件上传,RFC 中认为不会使其职责过重,反而迁移和兼容更易实现。

上传外部文件

使用 message/external-body 并设置 access-type: uri:xxxx 可以上传第三方的文件。

但这个用得不多,而且没有实际操作过。(别人也不会轻轻松松让你拿到文件的 uri 地址啊。。)

multipart/form-data 定义

RFC 中的例子一:

Content-type: multipart/form-data, boundary=AaB03x

--AaB03x
content-disposition: form-data; name="field1"

Joe Blow
--AaB03x
content-disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--AaB03x--

每个 form 表单元素由 boundary 进行分隔提交。每个属性都有 content-dispositionname 属性,对文件,还有表示原始文件名的 filename 属性。

默认表单元素的 Content-typetext/plain;文件为 application/octet-stream 或可自动检测到的类型;多个文件时为 multipart/mixed(见下面例子)。

当上传多个文件时,RFC 给出的例子二:

Content-type: multipart/form-data, boundary=AaB03x

--AaB03x
content-disposition: form-data; name="field1"

Joe Blow
--AaB03x
content-disposition: form-data; name="pics"
Content-type: multipart/mixed, boundary=BbC04y

--BbC04y
Content-disposition: attachment; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--BbC04y
Content-disposition: attachment; filename="file2.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary

...contents of file2.gif...
--BbC04y--
--AaB03x--

文件的 Content-type 属性被设置为 multipart/mixed,并启用了一个新的 boundary(相当于是一个嵌套形式)。每个文件使用新的 boundary 分隔,content-disposition 被设为 attachment.

content-transfer-encoding 被设置为 binary,指明该文件以二进制编码。

Each part may be encoded and the "content-transfer-encoding" header supplied if the value of that part does not conform to the default encoding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant