为什么不总是使用 enctype="multipart/form-data" 呢?

Why not use enctype="multipart/form-data" always?

通过更改,我发现 django 管理界面始终使用 enctype="multipart/form-data"

我想采用这种模式,但我不确定我是否看到了这带来的所有后果。

为什么不总是使用 enctype="multipart/form-data"

更新

一年多以来,我们总是以某种形式使用 enctype="multipart/form-data"。工作正常。

enctype 属性指定表单数据在提交到服务器时应如何编码,enctype="multipart/form-data" 在用户想要上传文件(图像、文本文件等)时使用。 ) 到服务器。

对简单的文本表单使用 multipart/form-data 会产生一些开销。比较带有姓名和电子邮件的简单表单。

默认(x-www-form-urlencoded)

Content-Type: application/x-www-form-urlencoded; charset=utf-8

name=Nomen+Nescio&email=foo%40bar.com

multipart/form-data

Content-Type: multipart/form-data; boundary=96a188ad5f9d4026822dacbdde47f43f

--96a188ad5f9d4026822dacbdde47f43f
Content-Disposition: form-data; name="name"

Nomen Nescio
--96a188ad5f9d4026822dacbdde47f43f
Content-Disposition: form-data; name="email"

foo@bar.com
--96a188ad5f9d4026822dacbdde47f43f

如您所见,使用多部分编码时,您需要在 body 中传输一堆额外的字节(本例中为 37 字节 vs 252 字节)

但是当您添加 http headers 并应用压缩时,在大多数实际情况下,负载的相对差异会小得多。

首选 urlencoded 而不是 multipart 的原因是可以节省 http 请求大小。

来自定义multipart/form-dataRFC

Many web applications use the "application/x-www-form-urlencoded" method for returning data from forms. This format is quite compact, for example:

name=Xavier+Xantico&verdict=Yes&colour=Blue&happy=sad&Utf%F6r=Send

However, there is no opportunity to label the enclosed data with a content type, apply a charset, or use other encoding mechanisms.

Many form-interpreting programs (primarily web browsers) now implement and generate multipart/form-data, but a receiving application might also need to support the "application/x-www-form-urlencoded" format.

除了让您上传文件外,multipart/form-data 还允许您使用其他字符集和编码机制。所以不使用它的唯一原因是:

  • 如果您想节省一点带宽(请记住,如果请求正文被压缩,这将不再是一个问题)。

  • 如果您需要支持无法处理文件上传且只知道 application/x-www-form-urlencoded 的老客户端,或者在处理 ASCII 以外的任何内容时遇到问题。

TL;博士

如果您针对任何现代浏览器并为任何机密数据使用 SSL,几乎可以肯定没有问题。

背景

form-data 类型最初是作为浏览器中文件上传的实验性扩展而开发的,如 rfc 1867. There were compatibility issues at the time, but if your target browsers supports HTML 4.x and hence the enc-type, you're fine. As you can see here 中所述,这对所有主流浏览器来说都不是问题。

正如在其他答案中已经指出的那样,它是一种更冗长的格式,但是当您可以压缩请求或者甚至仅仅依靠过去 20 年提高的通信速度时,这也不是问题。

最后,您还应该考虑滥用这种格式的可能性。由于它旨在上传文件,因此有可能被用于在用户不知情的情况下从用户的机器中提取信息,或者发送未加密的机密信息,如 the HTML spec 中所述。不过,现代浏览器再一次经过现场强化,如果让黑客滥用这么容易实现的目标并且您可以使用 HTTPS 获取机密数据,我会感到震惊。