天天看点

enctype ='multipart / form-data'是什么意思?

enctype='multipart/form-data'

在HTML表单中是什么意思,我们什么时候应该使用它?

#1楼

enctype='multipart/form-data'

表示不会编码任何字符。 这就是为什么在将文件上传到服务器时使用此类型的原因。

因此,当表单需要二进制数据(例如文件内容)上载时,将使用

multipart/form-data

#2楼

将方法属性设置为POST,因为无法使用表单将文件内容放入URL参数中。

将enctype的值设置为multipart / form-data,因为数据将分为多个部分,每个文件一个,另加一个可能随它们一起发送的表单主体文本。

#3楼

我们什么时候应该使用它

昆汀的答案是正确的:如果表单包含文件上传,则使用

multipart/form-data

否则使用

application/x-www-form-urlencoded

否则,如果省略

enctype

,则为默认设置。

我要去:

  • 添加更多HTML5参考
  • 用表单提交示例解释为什么他是对的

HTML5参考

enctype

有三种可能性 :

  • application/x-www-form-urlencoded

  • multipart/form-data

    (规范指向RFC7578 )
  • text/plain

    。 这是“无法可靠地由计算机解释的”,因此永远不要在生产中使用它,我们也不会对其进行深入研究。

如何生成示例

一旦您看到每种方法的示例,就会很清楚它们的工作方式以及何时使用每种方法。

您可以使用以下示例生成示例:

  • nc -l

    或ECHO服务器: HTTP测试服务器接受GET / POST请求
  • 用户代理,例如浏览器或cURL

将表单保存到最小的

.html

文件中:

<!DOCTYPE html>
<html >
<head>
  <meta charset="utf-8"/>
  <title>upload</title>
</head>
<body>
<form action="http://localhost:8000" method="post" enctype="multipart/form-data">
  <p><input type="text" name="text1" value="text default">
  <p><input type="text" name="text2" value="a&#x03C9;b">
  <p><input type="file" name="file1">
  <p><input type="file" name="file2">
  <p><input type="file" name="file3">
  <p><button type="submit">Submit</button>
</form>
</body>
</html>
           

我们将默认文本值设置为

a&#x03C9;b

,这意味着

aωb

因为

ω

U+03C9

,这是UTF-8中的字节

61 CF 89 62

创建要上传的文件:

echo 'Content of a.txt.' > a.txt

echo '<!DOCTYPE html><title>Content of a.html.</title>' > a.html

# Binary file containing 4 bytes: 'a', 1, 2 and 'b'.
printf 'a\xCF\x89b' > binary
           

运行我们的小回声服务器:

while true; do printf '' | nc -l 8000 localhost; done
           

在浏览器上打开HTML,选择文件,然后单击Submit并检查终端。

nc

打印收到的请求。

测试于:Ubuntu 14.04.3,

nc

BSD 1.105,Firefox 40。

多部分/表单数据

Firefox发送:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"

text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text2"

aωb
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

Content of a.txt.

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html

<!DOCTYPE html><title>Content of a.html.</title>

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file3"; filename="binary"
Content-Type: application/octet-stream

aωb
-----------------------------735323031399963166993862150--
           

对于二进制文件和文本字段,按字面意义发送字节

61 CF 89 62

(UTF-8中的

aωb

)。 您可以使用

nc -l localhost 8000 | hd

nc -l localhost 8000 | hd

,表示字节:

61 CF 89 62
           

被发送(

61

=='a'和

62

=='b')。

因此很明显:

  • Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266

    Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266

    将内容类型设置为

    multipart/form-data

    并说字段由给定分隔

    boundary

    字符串。
  • 每个字段在其数据之前都有一些子标题:

    Content-Disposition: form-data;

    ,字段

    name

    filename

    以及数据。

    服务器读取数据,直到下一个边界字符串为止。 浏览器必须选择一个不会出现在任何字段中的边界,因此这就是请求之间边界可能有所不同的原因。

    由于我们具有唯一的边界,因此无需对数据进行编码:按原样发送二进制数据。

    TODO:最佳边界尺寸(我打赌的

    log(N)

    )是什么,找到它的算法的名称/运行时间是多少? 在以下位置询问: https : //cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences
  • Content-Type

    由浏览器自动确定。

    在以下位置询问如何确定它:浏览器如何确定上载文件的mime类型?

应用程序/ x-www-form-urlencoded

现在更改

enctype

application/x-www-form-urlencoded

,重新加载浏览器,然后重新提交。

Firefox发送:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: application/x-www-form-urlencoded
Content-Length: 51

text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary
           

显然,没有发送文件数据,仅发送了基名。 因此,这不能用于文件。

对于文本字段,我们看到通常可打印的字符(例如

a

b

)以一个字节发送,而不可打印的

0xCF

(例如

0xCF

0x89

)每个占用3个字节 :

%CF%89

比较方式

文件上载通常包含许多不可打印的字符(例如图像),而文本形式几乎从来没有。

从示例中我们可以看到:

  • multipart/form-data

    :给消息增加了一些边界开销字节,并且必须花费一些时间来计算它,但是每个字节以一个字节发送。
  • application/x-www-form-urlencoded

    :每个字段(

    &

    )具有单个字节边界,但是为每个不可打印字符增加了3倍的线性开销因子。

因此,即使我们可以发送带有

application/x-www-form-urlencoded

,我们也不

application/x-www-form-urlencoded

,因为它效率很低。

但是对于在文本字段中找到的可打印字符来说,这无关紧要,并且产生的开销更少,因此我们只使用它。

#4楼

  • enctype( ENC ode TYPE )属性指定将表单数据提交到服务器时应如何编码。
  • multipart / form-data是enctype属性的值之一,该属性在具有文件上传功能的表单元素中使用。 多部分是指表单数据分为多个部分并发送到服务器。

#5楼

通常这是当您有一个POST表单,需要将文件上传作为数据时...这将告诉服务器它将如何对传输的数据进行编码,在这种情况下,它将不会被编码,因为它只会传输并上传文件上传到服务器,例如上传图像或pdf时

#6楼

发出POST请求时,必须以某种方式对构成请求主体的数据进行编码。

HTML表单提供了三种编码方法。

  • application/x-www-form-urlencoded

    (默认)
  • multipart/form-data

  • text/plain

正在添加

application/json

,但已被放弃。

(使用HTML表单提交以外的其他方式生成的HTTP请求也可以使用其他编码。)

格式的细节对大多数开发人员而言并不重要。 要点是:

  • 切勿使用

    text/plain

在编写客户端代码时:

  • 当表单包含任何

    <input type="file">

    元素时,请使用

    multipart/form-data

  • 否则,您可以使用

    multipart/form-data

    application/x-www-form-urlencoded

    application/x-www-form-urlencoded

    会更有效

在编写服务器端代码时:

  • 使用预先编写的表单处理库

大多数(例如Perl的

CGI->param

或PHP的

$_POST

超全局变量公开的

CGI->param

)将为您解决这些差异。 不要费力尝试解析服务器收到的原始输入。

有时您会发现一个无法处理两种格式的库。 Node.js最受欢迎的用于处理表单数据的库是body-parser ,它无法处理多部分请求(但是有文档建议一些可能的替代方法)。

如果要编写(或调试)用于解析或生成原始数据的库,则需要开始担心格式。 为了您的利益,您可能还想了解它。

application/x-www-form-urlencoded

与URL末尾的查询字符串大致相同。

multipart/form-data

要复杂得多,但是它允许整个文件包含在数据中。 结果的一个示例可以在HTML 4规范中找到 。

text/plain

由HTML 5引入,仅在调试时有用-从规范上来说 : 它们不能由计算机可靠地解释 -我认为其他结合了工具(例如大多数浏览器的开发人员工具中的Net标签) )对此更好)。

#7楼

enctype='multipart/form-data

是一种编码类型,它允许通过POST发送文件。 很简单,没有这种编码,文件将无法通过POST发送。

如果要允许用户通过表单上传文件,则必须使用此enctype 。

#8楼

提交表单时,您告诉浏览器通过HTTP协议在网络上发送一条消息,该消息已正确封装在TCP / IP协议消息结构中。 HTML页面具有一种将数据发送到服务器的方式:使用

<form>

提交表单后,如果创建了HTTP请求并将其发送到服务器,则该消息将包含表单中的字段名称以及用户填写的值。 这种传输可以通过

POST

GET

HTTP方法进行 。

  • POST

    告诉浏览器构建一条HTTP消息并将所有内容放入消息正文中(这是一种非常有用的处理方式,更加安全且灵活)。
  • GET

    将在querystring中提交表单数据。 它对数据表示和长度有一些限制。

说明如何将表格发送到服务器

仅当使用

POST

方法时,属性

enctype

才有意义。 指定时,它指示浏览器通过以特定方式对内容进行编码来发送表单。 从MDN-表单enctype :

当method属性的值为post时,enctype是用于将表单提交给服务器的内容的MIME类型。
  • application/x-www-form-urlencoded

    :这是默认设置。 发送表单后,将收集所有名称和值,并对最后一个字符串执行URL编码 。
  • multipart/form-data

    :字符未编码。 当表单具有文件上载控件时,这一点很重要。 您要发送文件二进制文件,这样可以确保比特流不会改变。
  • text/plain

    :转换空格,但不再执行编码。

安全

提交表单时,可能会出现一些安全问题,如RFC 7578第7节:多部分表单数据-安全考虑 :

所有表格处理软件都应处理用户提供的表格数据

敏感,因为它通常包含机密信息或个人信息

识别信息。 Web浏览器中广泛使用表单“自动填充”功能。 这些可能被用来欺骗用户

否则会在不知不觉中发送机密信息

无害的任务。 multipart / form-data不提供任何功能

用于检查完整性,确保机密性,避免用户

混乱或其他安全功能; 这些问题一定是

由表单填充和表单数据解释应用程序解决。

接收表单并处理表单的应用程序必须小心,不要将数据发送回原本不希望发送的表单处理站点。

解释Content-文件名时,这一点很重要-

处置标头字段,以防止在不经意间覆盖文件中的文件

收件人的文件空间。

如果您是开发人员,并且服务器将处理用户提交的表单,这些表单最终可能包含敏感信息,则这与您有关。

#9楼

enctype属性指定将表单数据提交到服务器时应如何编码。

仅当method =“ post”时才可以使用enctype属性。

没有字符被编码。 当您使用具有文件上载控件的表单时,此值是必需的

从W3Schools