enctype ='multipart / form是什么?

enctype='multipart/form-data'HTML表单中enctype='multipart/form-data'含义是什么以及我们应该在什么时候使用它?


当您发出POST请求时,您必须以某种方式编码形成请求主体的数据。

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

  • application/x-www-form-urlencoded (默认)
  • multipart/form-data
  • text/plain
  • 正在完成添加application/json ,但已经放弃了。

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

    在编写客户端代码时,您需要知道的仅仅是当表单包含任何<input type="file">元素时使用multipart/form-data

    在编写服务器端代码时: 使用预先写好的表单处理库 (例如,Perl的CGI->param或由PHP的$_POST superglobal公开的那个),它将为您处理差异。 不要试图解析服务器收到的原始输入。

    切勿使用text/plain


    如果您正在编写(或调试)库来解析或生成原始数据,那么您需要开始担心格式。 你可能也想知道它的利益。

    application/x-www-form-urlencoded或多或少与URL末尾的查询字符串相同。

    multipart/form-data明显更复杂,但它允许将整个文件包含在数据中。 结果的一个例子可以在HTML 4规范中找到。

    text/plain由HTML 5引入,仅用于调试 - 从规范:它们不能被计算机可靠地解释 - 我会争辩说其他文件与工具相结合(如大多数浏览器的开发人员工具中的Net标签)更好)。


    我们应该什么时候使用它

    Quentin的答案是正确的:如果表单包含文件上传,则使用multipart/form-data否则使用application/x-www-form-urlencoded ,如果您省略enctype ,则默认为默认值。

    我要去:

  • 添加更多HTML5参考
  • 用一个表单提交示例解释他为什么正确
  • HTML5参考

    enctype有三种可能性:

  • x-www-urlencoded
  • multipart/form-data (spec指向RFC7578)
  • text-plain 。 这是“不可靠的电脑解释”,所以它不应该用于生产,我们不会进一步考虑。
  • 如何生成示例

    一旦你看到每种方法的例子,就会明白它们是如何工作的以及何时应该使用每一种方法。

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

  • nc -l或ECHO服务器
  • 像浏览器或cURL这样的用户代理
  • 将表单保存为最小的.html文件:

    <!DOCTYPE html>
    <html lang="en">
    <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 'axCFx89b' > binary
    

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

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

    在浏览器中打开HTML,选择文件并点击提交并检查终端。

    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; ,字段namefilename ,后面跟着数据。

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

    由于我们有独特的边界,因此不需要编码数据:二进制数据按原样发送。

    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窗体-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
    

    很显然,文件数据并未发送,只有基本名称。 所以这不能用于文件。

    至于文本字段,我们看到像ab这样a通常的可打印字符以一个字节发送,而不可打印的0xCF0xCF0x89分别占用3个字节%CF%89

    对照

    文件上传通常包含很多不可打印的字符(例如图像),而文本表单几乎从不做。

    从我们看到的例子来看:

  • multipart/form-data :将几个字节的边界开销添加到消息中,并且必须花费一些时间计算它,但将每个字节发送一个字节。

  • application/x-www-form-urlencoded :每个字段( & )具有单个字节边界,但为每个不可打印字符添加3x的线性开销因子。

  • 因此,即使我们可以发送带有application/x-www-form-urlencoded ,我们也不想这样做,因为它效率太低。

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


    enctype='multipart/form-data是一种允许通过POST发送文件的编码类型。 很简单,没有这种编码,文件不能通过POST发送。

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

    链接地址: http://www.djcxy.com/p/3777.html

    上一篇: What does enctype='multipart/form

    下一篇: International characters in filename in mutipart formdata