您的位置:首页 > Web前端 > HTML

[RFC1867] HTML中基于表单的文件上传

2016-04-19 13:11 435 查看


网络工作组:E. Nebel

征求意见:1867 L. Masinter

类别:试验 施乐公司

十一月 1995

HTML中基于表单的文件上传

这个备忘录的状态

这个备忘录为互联网社区定义了一个试验协议。这个备忘录不提出任何形式的互联网标准。对该备忘录改良的讨论和建议是需要的。这个备忘录的讨论是无限制的。

1. 摘要

目前,HTML表单允许表单的制造者向浏览表单的用户获取信息。这些表单已经被证明在各种必须由用户输入信息的应用程序中是有用的。然而,这一能力是受限的,因为HTML表单没有提供要求用户提交文件数据的方式。服务供应商需要从用户处获取文件,不得不实现自定义用户应用程序。(例如本站的自定义应用程序已在www-talk邮箱列表页披露。)自从文件上传成为一个受益许多应用程序的特性,此处提议一种HTML扩展来允许提供一致地表达文件上传请求的信息,以及为文件上传响应使用兼容MIME的表现形式。此处还包括一个向下兼容策略的描述,它允许新的服务器与当前HTML客户端交互。

此提议是独立于任何HTML版本的。它成为了一个部件。

2. 带文件提交的HTML表单

当前HTML标准为INPUT标签的TYPE属性定义了八个可接受的值:CHECKBOX、HIDDEN、IMAGE、PASSWORD、RADIO、RESET、SUBMIT、TEXT。

此外,它定义当使用POST METHOD时,FORM标签的ENCTYPE属性默认使用"application/x-www-form-urlencoded"值。

这个提议对HTML做了两个改变:

1) 为INPUT标签的TYPE属性增加一个FILE选项。

2) 为INPUT标签允许标注ACCEPT属性,它表示允许输入的多媒体类型或文件类型的列表。

此外,它定义了一个新的MIME多媒体类型multipart/form-data,并说明了当HTML客户端解析一个带ENCTYPE="multipart/form-data"或<INPUT type="file">标签时的行为。

这些改变可以被认为是独立的,但对合理的文件上传功能来说都是必须的。

HTML表单的开发者想从用户那里请求一个或多个文件时可以如下编写(例如):

<FORM ENCTYPE="multipart/form-data" ACTION="_URL_" METHOD=POST>

待处理文件:<INPUT NAME="userfile1" TYPE="file">

<INPUT TYPE="submit" VALUE="Send File">

</FORM>

对HTML DTD的改变是对"InputType"实体增加了一个选项。此外,还提议INPUT标签需有一个ACCEPT属性,它是一个逗号分隔的多媒体类型列表。

... (其他标签) ...

<!ENTITY % InputType "(TEXT | PASSWORD | CHECKBOX |

RADIO | SUBMIT | RESET |

IMAGE | HIDDEN | FILE )">

<!ELEMENT INPUT - 0 EMPTY>

<!ATTLIST INPUT

TYPE %InputType TEXT

NAME CDATA #IMPLIED -- required for all but submit and reset

VALUE CDATA #IMPLIED

SRC %URI #IMPLIED -- for image inputs --

CHECKED (CHECKED) #IMPLIED

SIZE CDATA #IMPLIED --like NUMBERS,

but delimited with comma, not space

MAXLENGTH NUMBER #IMPLIED

ALIGN (top|middle|bottom) #IMPLIED

ACCEPT CDATA #IMPLIED --list of content types

>

... (其他标签) ...

3. 建议实现方案

当客户端解析HTML时有宽广的途径供选择,并从中挑选最合适的机制来处理HTML上下文,这部分为客户端中的一类——WWW浏览器,提供了实现文件上传的建议。

3.1 FILE组件的显示

当遇到一个FILE类型的INPUT标签时,浏览器可以显示(所选的)文件名列表,以及一个"Browse"按钮或其他选择方式。选中"Browse"按钮可能导致浏览器为系统打开一个适用于文件选取的模式面板。例如基于窗口的浏览器可以弹出一个文件选取窗口。这样一个文件选取对话弹窗,用户应该有代替当前所选文件的选项、添加一个新文件等的选项。浏览器实现者应该选择文件名称列表可被用户手动编辑。

如果遇到ACCEPT属性,浏览器可以标记所限定的文件格式并对系统验证所选文件对应的后缀。

3.2 提交响应

当用户完成表单并选中SUBMIT标签时,浏览器应该发送表单数据以及所选文件内容到服务器。编码类型application/x-www-form-urlencoded对于发送大量二进制数据或发送包含非ASCII字符的文本是低效的。因此,一个新的多媒体类型——multipart/form-data被提议作为高效发送与表单所填内容相关的值的方法从客户端发送到服务器。

3.3 multipart/form-data的使用

multipart/form-data的设定被包括在第7章节。它的范围被选定为包括不出现任何数据。(这一情况有时是很可能发生的。)表单的每一个字段都将按照它在表单中出现的顺序作为多部分数据流的一部分被发送。每一部分都有在原始HTML表单中INPUT标签的name属性标识。如果多媒体类型是已知的,则每一部分都应该被适当的content-type标记(例如通过文件后缀或操作系统类型信息来判断)否则作为application/octet-stream标记。

如果多个文件被选取,它们应该被转换到一起使用multipart/mixed格式。

虽然HTTP协议可以传送任意的二进制数据,邮件传送(如果ACTION是”mailto:”URL)被定义使用7位编码。如果值不符合默认编码则该部分被提供的值可能需要编码以及提供"content-transfer-encoding"标识头。[查看RFC
1521第5章节以获得更多细节。]

原始本地文件名可能也要被提供,也作为'filename'参数以及'content-disposition: form-data'标识头或在多文件上传的情况下记录在子部份的'content-disposition: file'标识头中。客户端应用程序应该尽量提供文件名;如果客户端操作系统的文件名不是US-ASCII的,文件名可以使用近似或完全与RFC 1522相同的方法。在一些情况下这是遍历的,例如所上传的每个文件可能都包含引用文件,例如一个TeX文件以及它的.sty辅助样式描述文件。

在服务器端,ACTION可能指向一个HTTP URL,它通过CGI来实现表单响应。在这种情况下,CGI程序将注意content-type是multipart/form-data并解析各个字段(检查正确性,等待本地文件的文件数据以供后续处理等)。

3.4 其他属性的解析

<INPUT TYPE=file> 标签可以使用VALUE属性来定义默认文件名。这样使用可能依赖系统。但在多于一个事务的序列中它可能是有用的,例如避免一次又一次提示用户文件重名。

SIZE属性可以使用SIZE=宽,高来指定,宽是默认为文件名宽,高是所选文件列表显示大小的预期。例如,这对于表单设计者来说是有用的,他们期望上传多个文件并想在浏览器展现一个(最好在旁边附带”browse”按钮的)多文件输入元素。当没有指定高时(当表单设计者期望仅上传一个文件),它对展现一个单行文本输入元素是有用的。当高大于1时(当表单设计者期望上传多个文件),它展现一个带滚动条的多行文本区域。

4. 向下兼容问题

虽然没有必要为了成功适配并改良当前互联网表单机制,但也对预期的迁移策略有帮助:旧浏览器的用户也可以通过使用一个帮助应用程序来实现文件上传对话弹窗。当使用<INPUT TYPE=FILE>时,大多数当前的web浏览器将像对待<INPUT TYPE=TEXT>一样处理并给用户一个文本框。用户可以键入一个文件名到这个文本框中。此外,当前浏览器似乎忽略了<FROM>标签中的ENCTYPE属性,并且将数据作为application/x-www-form-urlencoded传送。

因此,CGI服务器可以编写一种判断方法,如果表单数据返回的content-type使用application/x-www-form-urlencoded来代替multipart/form-data,就确定用户使用的浏览器没有实现文件上传。

在这种情况下,CGI服务器可以返回一个数据流来代替返回"text/html"响应,它通过一个帮助应用程序来实现;它是一个"application/x-please-send-files"类型的数据流,它包括:

* 从表单获取的要提交的实际(完全合规的)URL(用CRLF终结)

* 作为文件内容的属性名列表(空格分隔,用CRLF终结)

* 从客户端到服务器端的完整原始application/x-www-form-urlencoded表单数据

在这种情况下,浏览器需要配置一个应用程序来开始处理application/x-please-send-files。

帮助应用程序可以读取表单数据,并注意哪一个字段包含本地文件名然后要用它们的文件数据内容来替换。它可能会提示用户改变了或添加了可用文件到列表中,然后封装数据与文件内容,使用multipart/form-data传回服务器。

首先帮助应用程序可以生成那种现代浏览器实际发送的数据,这是为了能一致地发送到原始ACTION URL进行处理【译注:解耦和】。此处的要点是服务器可以使用*同一个*CGI来为旧的以及新的浏览器实现文件上传机制。

帮助应用程序不需要显示表单数据,但应该确认确实提示了用户请求发送的数据是适宜的(这避免了恶意服务器的安全问题,它们请求上传的文件实际上没有提示用户。)如果可以显示所涉及的文件的传输状态就是有用的。

5. 其他注意事项

5.1 压缩,加密

本方案没有对文件提出可能的压缩。经过一番考虑之后,似乎文件压缩的优化问题对于浏览器自动决定文件应该如何被压缩太复杂了。许多链路层传送机制(如高速解调器)在链路上执行数据压缩,但在这层进行压缩优化可能是不恰当的。对于浏览器来说,优化为文件数据生成一个x-compress的content-transfer-encoding是可能的,如果需要并在服务器处理之前解压缩数据;然而这是提议之外的事。

同样的,本提议不包括数据的加密机制;这应该由其他机制在适合数据安全传输的阶段处理或通过安全HTTP、邮件处理。

5.2 文件延迟传输

在一些情况下,在准备实际接收数据之前,服务器验证各个元素的表单数据(用户名,帐号等)可能是明智的。然而,经过一番考虑之后,似乎最好先请求实现验证的服务器以处理一系列表单【译注:解耦和】,在服务器端,部分数据标签事先验证并本发送回客户端作为’hidden’隐藏字段,或安排表单中需要验证的元素首先出现。它对想要构建复杂应用程序的服务器负责保持事务的状态,而也允许那些有简单输入框的情况需要去构建简单的应用程序。

HTTP协议可能要求一个content-length来帮助全部传输。 即使它不这样做,还是鼓励HTTP客户端为所有文件输入框提供content-length以便于一个忙碌的服务器在提供的文件数据太大时可以决定是否能合适地处理或仅返回一个错误编码并关闭连接不等待全部传入的文件都处理完。当前一些CGI的实现要求在所有POST事务中都有一个content-length。

如果INPUT标签包含MAXLENGTH属性,客户端应该考虑它的值作为最大content-length(字节)即服务器可以接收的文件大小。以这种方式,服务器在上传发生之前可以提示客户端它们为文件上传提供多少空间。然而,需重点注意这仅仅是一个提示,服务器的实际需求可能在表单创建与提交之间发生改变。

无论何时,如果所接收文件太大,HTTP服务器可能在事务的中间终止文件上传。

5.3 发送及返回二进制文件的其他选择

许多人建议使用新mime顶级类型”aggregate”,例如aggregate/mixed或”packet”的content-transfer-encoding来表示不定长二进制数据,而不是依赖multipart-style边界。尽管我们不返对这样做,但这需要增加设计以及标准化的工作来接纳”aggregate”。另一方面,'multipart'机制是建设完善的,在发送的客户端和接收的服务器端都能简单实现并且它与处理多组合二进制数据的其他方法效率一样好。

5.4 非多态<INPUT>标签:

许多人想知道为实现文件上传功能不是仅提供一个不同类型的FORM子标签而是多态'INPUT'标签的明智之处。在其他考虑中,使用<INPUT>标签其迁移策略是重要因素。此外,<INPUT>标签已经多态出大部分种类的数据输入而不是创建多种<INPUT>标签,增强<INPUT>标签似乎是最适合的方式。INPUT标签的'type'属性不是content-type的返回内容,而是一个种宽泛类型,即它标识用户的互动样式。在此的描述被小心地编写以让 <INPUT
TYPE=FILE>即可工作于文本浏览器也可工作于音频标记。

5.5 字段数据的默认content-type值

在HTML中许多输入字段都被要求输入。表单数据应该如果被传送回服务器是存在歧义的。 让<INPUT>标签的content-type属性使用text/plain是清晰且无歧义的,客户端应该在以CRLF结尾发送数据回服务器之前正确地对数据编码。

5.6 允许表单ACTION值为"mailto:"

此与本提议无关,但对于HTML解析客户端允许表单ACTION值为"mailto:"URL是非常有用的。这似乎像是一个好主意,无论包不包括在提议内。同样地对于通过邮件收到的表单ACTION应该默认为"reply-to:"信息。 这两个提议可以允许HTML表单通过HTTP服务器处理但通过邮件回复,换句话说允许HTML表单通过邮件发送,并由HTML填写收件人并邮件回复。

5.7 使用第三方传送远程文件

在某些情况下,用户想操作客户端程序提出一个远程数据的URL而不是本地文件。在这种情况下,有没有方法来允许浏览器发送一个客户端指针来指向额外数据而不是发送完整内容?这种能力可以通过客户端发送给服务器端的数据为以"message/external-body"做为类型,"access-type"在信息主体设为远程数据的"uri"或URL来实现。

5.8 使用ENCTYPE=x-www-form-urlencoded发送文件

如果一个表单包含<INPUT TYPE=file>标签但在封闭的<FORM>中没有包含ENCTYPE,即处理方式是没有进行指定的。这可能使用URN进行大量不适当的数据编码尝试,而这并不是我们想要的数据。

5.9 使用CRLF作为行分隔符

如同所有MIME传送,CRLF在multipart/form-data数据的POST传送中被用来作为行分隔符。

5.10 与multipart/related的关系

MIMESGML组织正提出一个称为multipart/related的新类型。 而它包含与multipart/form-data相似的功能,multipart/related的使用与表单数据的应用程序是不同的,所以表单数据被分开描述。

它可能在一些时候使用multipart/related,在body部分对HTML表单的结果(包括文件)进行编码;这与本提示是兼容并存的。

5.11 非ASCII字段名

注意MIME表示头被要求生成为使用US-ASCII字符集的仅由7位构成的数据。因此如果字段名包含字符集编码以外的字符则应该按照RFC1522规定进行编码。在HTML2.0中,默认字符集是ISO-8859-1,但在字段名中的非ASCII字符应该被编码。

6. 例子

假设服务器提供如下HTML:

<FORM ACTION="http://server.dom/cgi/handle"

ENCTYPE="multipart/form-data"

METHOD=POST>

你叫什么名字?<INPUT TYPE=TEXT NAME=submitter>

你要发送什么文件?<INPUT TYPE=FILE NAME=pics>

</FORM>

然后用户在姓名字段输入"Joe Blow"并选择一个文本文件"file1.txt"来回复'你要发送什么文件?'

客户端可能传回如下数据:

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

... file1.txt的内容 ...

--AaB03x--

如果用户还指定一个图片文件"file2.gif"来回复'你要发送什么文件?',客户端可能传回如下数据:

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

... file1.txt的内容 ...

--BbC04y

Content-disposition: attachment; filename="file2.gif"

Content-type: image/gif

Content-Transfer-Encoding: binary

...file2.gif的内容 ...

--BbC04y--

--AaB03x--

7. multipart/form-data的记录

多媒体类型multipart/form-data遵循在RFC1521中列出的全部多部分MIME数据流的规则。它被期望用于来自表单所填写的返回数据。在一个表单里(尽管其他应用程序也使用表单,但指的是HTML表单),填表的用户提供了一系列的字段。每个字段都有名字。在给定的表单内,名字是唯一的。

multipart/form-data包含一系列部分。每一部分都要求包含一个"值为form-data"的content-disposition标识头,并且name属性说明表单内的字段名,例如,'content-disposition: form-data; name="xxxxx"',xxxxx是字段的名称。原始字段名使用非ASCII字符集的可使用RFC1522所列方法编码。

正如全部的多类型MIME的类型一样,每一个部分都有一个默认为text/plain的Content-Type选项。如果文件的内容通过填写表单被返回,而后如果知道文件类型则文件输入会被识别为application/octet-stream或适当的多媒体类型。如果多部分文件作为一个单一表单的整体结果而被返回,则它们可以做为multipart/mixed嵌入到multipart/form-data中返回。

每一部分都将被编码但如果某部分的值不符合默认编码则由"content-transfer-encoding"标识头提供编码。

文件选中后也可能被标记文件名。文件名可以使用"content-disposition"标识头的'filename'参数来描述。虽然这不是必选项,但当原始文件名是已知时强烈推荐在任何情况下都提供。在许多应用程序中这是有用或必须的。

8. 安全注意事项

客户端没发送任何文件即没有明确要求用户一定要上传文件是重要的事。因此HTML解析器期望建议由<INPUT TYPE=file VALUE="yyyy">来确定默认文件名。没有任何隐藏字段去指定任何文件。

本提议不包含数据加密机制;这应该由任意在数据传输安全方面的其他机制处理,或者通过安全HTTP或MOSS(在RFC1848中描述)提供安全功能。

一旦文件被上传,它就会被接收处处理并以适当方式存储文件。

9. 结论

本建议的实现给予客户端在发送到服务器端的文件数量及类型上许多扩展性,它给予服务器端决定接受文件的控制权以及它给予服务器端跟不支持INPUT TYPE为"file"的浏览器交互的可能。

对HTML DTD的改变是非常简单的,但非常强大。它使更多不同种类的服务可通过互联网实现文件上传并且是当前可能最缺乏的文件上传方案。这对于互联网的能力来说将是非常有价值的增强功能。

作者地址

Larry Masinter

施乐PARC

加利福尼亚州帕罗奥多市土狼山路3333号 94304

电话:(415) 812-4365

传真:(415) 812-4333

邮箱:masinter@parc.xerox.com

Ernesto Nebel

XSoft,施乐公司

加利福尼亚州圣迭戈市贝纳多牧场路10875号200房 92127-2116

电话:(619) 676-7817

传真:(619) 676-7865

邮箱:nebel@xsoft.sd.xerox.com

A. multipart/form-data所记录的多媒体类型

多媒体类型名:multipart

多媒体子类型名:form-data

必填参数:无

选填参数:无

编码注意事项:对于其他多部分类型相比没有更多注意事项。

发行标准:RFC 1867

安全注意事项

multipart/form-data类型除了可能出现的附属部分,其自身没有新的安全注意事项。

参考

[RFC 1521] MIME(多用途网络邮件扩展)第一部分:提出网络消息主体提出一种机制并对其进行描述。N. Borenstein & N. Freed.1993九月。

[RFC 1522] MIME(多用途网络邮件扩展)第二部分:对非ASCII文本的消息标识头扩展。K. Moore.1993九月。

[RFC 1806] 交流报告信息:网络消息中的:Content-Disposition标识头。R. Troost & S. Dorner,1995六月。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: