zoukankan      html  css  js  c++  java
  • multipart/form-data和application/x-www-form-urlencoded区别

    FORM元素的enctype属性指定了表单数据向服务器提交时所采用的编码类型。
    例如:
      application/x-www-form-urlencoded: 窗体数据被编码为名称/值对。这是标准的编码格式。
      multipart/form-data: 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分,这个一般文件上传时用。
      text/plain: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符

    FORM的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded,但在向服务器发送大量的文本、包含非ASCII字段的文本或者二进制数据时,application/x-www-form-urlencoded编码方式效率较低(每个非字母数字字符都将由一个% 和代表字符编码的两个十六进制数代替,这增加了传输非字母数字字符的数据量),所以在文件上载时,所使用的编码类型应当是“multipart/form-data”,它告诉我们传输的数据要用到多媒体传输协议,由于多媒体传输的都是大量的数据,multipart/form-data既可以发送文本数据,也可以支持二进制数据上传。

    当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2…),然后把这个字串append到url后面,用?分割,加载这个新的url;

    当action为post时候,浏览器把form数据封装到http body中,名称/值对之间用&分隔,然后发送到server。 如果没有type=file(表示文件上传)的控件,用默认的application/x-www-form-urlencoded就可以了。 但是如果有type=file的话,就要用到multipart/form-data了。浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)。

    为什么要用使用application/x-www-form-urlencoded作为默认方式,而不是multipart/form-data?

    答:因为在使用form-data格式时,消息体中每一个部分都要加上像Content-Type、Content-Disposition这样MIME头,对于较短的字母数字数据(大部分web表单),使用application/x-www-form-urlencoded方式,编码的代码更小。

    参考:https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data

    参考的stackoverflow答案如下:

    Summary; if you have binary (non-alphanumeric) data (or a significantly sized payload) to transmit, use multipart/form-data. Otherwise, use application/x-www-form-urlencoded.


    The MIME types you mention are the two Content-Type headers for HTTP POST requests that user-agents (browsers) must support. The purpose of both of those types of requests is to send a list of name/value pairs to the server. Depending on the type and amount of data being transmitted, one of the methods will be more efficient than the other. To understand why, you have to look at what each is doing under the covers.

    For application/x-www-form-urlencoded, the body of the HTTP message sent to the server is essentially one giant query string -- name/value pairs are separated by the ampersand (&), and names are separated from values by the equals symbol (=). An example of this would be: 

    MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

    According to the specification:

    [Reserved and] non-alphanumeric characters are replaced by `%HH', a percent sign and two hexadecimal digits representing the ASCII code of the character

    That means that for each non-alphanumeric byte that exists in one of our values, it's going to take three bytes to represent it. For large binary files, tripling the payload is going to be highly inefficient.

    That's where multipart/form-data comes in. With this method of transmitting name/value pairs, each pair is represented as a "part" in a MIME message (as described by other answers). Parts are separated by a particular string boundary (chosen specifically so that this boundary string does not occur in any of the "value" payloads). Each part has its own set of MIME headers like Content-Type, and particularly Content-Disposition, which can give each part its "name." The value piece of each name/value pair is the payload of each part of the MIME message. The MIME spec gives us more options when representing the value payload -- we can choose a more efficient encoding of binary data to save bandwidth (e.g. base 64 or even raw binary).

    Why not use multipart/form-data all the time? For short alphanumeric values (like most web forms), the overhead of adding all of the MIME headers is going to significantly outweigh any savings from more efficient binary encoding.

     

    只为训练自己,时刻锤炼一个程序员最基本的技能!
  • 相关阅读:
    hdu-1862 EXCEL排序
    hdu-1754 I Hate It
    hdu-1538 A Puzzle for Pirates
    在Window下安装Linux (ubuntu-16.04.2)
    Python爬虫--简单的单词查询
    Linux下MySQL在知道密码的情况下修改密码
    Linux下忘记MySQL密码的解决方法和输入mysqld_safe --skip-grant-tables &后无法进入MySQL的解决方法
    Python的下载及安装
    在Netbeans的项目中添加JDBC驱动程序
    Mac下截屏方法
  • 原文地址:https://www.cnblogs.com/coding-wtf/p/8909393.html
Copyright © 2011-2022 走看看