zoukankan      html  css  js  c++  java
  • 浏览器行为:Form表单提交

    1、form表单常用属性

    1
    2
    3
    4
    action:url 地址,服务器接收表单数据的地址
    method:提交服务器的http方法,一般为post和get
    name:最好好吃name属性的唯一性
    enctype: 表单数据提交时使用的编码类型,默认使用"pplication/x-www-form-urlencoded",如果是使用POST请求,则请求头中的content-type指定值就是该值。如果表单中有上传文件,编码类型需要使用"multipart/form-data",类型,才能完成传递文件数据。

     enctype为form表单数据的编码格式,Content-type为Http传输的数据的编码格式。分清两者

    2、浏览器提交表单时,会执行如下步骤

    1
    2
    3
    4
    1、识别出表单中表单元素的有效项,作为提交项
    2、构建一个表单数据集
    3、根据form表单中的enctype属性的值作为content-type对数据进行编码
    4、根据form表单中的action属性和method属性向指定的地址发送数据

    3、提交方式

    1
    2
    1、get:表单数据会被encodeURIComponent后以参数的形式:name1=value1&name2=value2 附带在url?后面,再发送给服务器,并在url中显示出来。
    2、post:enctype 默认"application/x-www-form-urlencoded"对表单数据进行编码,数据以键值对在http请求体重发送给服务器;如果enctype 属性为"multipart/form-data",则以消息的形式发送给服务器。

     

    Http协议行为:Http1.1协议

    我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。类似于下面这样:

    1
    <method> <request-URL> <version> <headers> <entity-body>  

    协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。

    但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。

    所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分

     Post请求下的Content-Type类型(编码类型)

    1.application/x-www-form-urlencoded

    这应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):

    1
    2
    3
    4
    POST http://www.example.com HTTP/1.1
    Content-Type: application/x-www-form-urlencoded;charset=utf-8
     
    title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

    首先,Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。例如 PHP 中,$_POST['title'] 可以获取到 title 的值,$_POST['sub'] 可以得到 sub 数组。

    很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」。

    2.multipart/form-data

    这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data。

    直接来看一个请求示例:

    form表单:

    1
    2
    3
    4
    5
    6
    <form action="/upload" enctype="multipart/form-data" method="post">
        Username: <input type="text" name="username">
        Password: <input type="password" name="password">
        File: <input type="file" name="file">
        <input type="submit">
    </form>

     Http协议请求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    POST http://www.example.com HTTP/1.1
    Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
     
    ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
    Content-Disposition: form-data; name="text"
     
    title
    ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
    Content-Disposition: form-data; name="file"; filename="chrome.png"
    Content-Type: image/png
     
    PNG ... content of chrome.png ...
    ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

     

    这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。

    这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。

    上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 <form> 表单也只支持这两种方式(通过 <form> 元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded。其实 enctype 还支持 text/plain,不过用得非常少)。

    随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

    3.application/json

    application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

    JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。

    Google 的 AngularJS 中的 Ajax 功能,默认就是提交 JSON 字符串。例如下面这段代码:

    1
    2
    3
    4
    var data = {'title':'test''sub' : [1,2,3]};
    $http.post(url, data).success(function(result) {
        ...
    });

    最终发送的请求是:

    1
    2
    3
    4
    POST http://www.example.com HTTP/1.1
    Content-Type: application/json;charset=utf-8
     
    {"title":"test","sub":[1,2,3]}
    这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。各大抓包工具如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示 JSON 数据,非常友好。但也有些服务端语言还没有支持这种方式,例如 php 就无法通过 $_POST 对象从上面的请求中获得内容。这时候,需要自己动手处理下:在请求头中 Content-Type 为 application/json 时,从 php://input 里获得原始输入流,再 json_decode 成对象。一些 php 框架已经开始这么做了。

    当然 AngularJS 也可以配置为使用 x-www-form-urlencoded 方式提交数据。如有需要,可以参考这篇文章

     

    4.text/xml

    它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。典型的 XML-RPC 请求是这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    POST http://www.example.com HTTP/1.1
    Content-Type: text/xml
     
    <?xml version="1.0"?>
    <methodCall>
        <methodName>examples.getStateName</methodName>
        <params>
            <param>
                <value><i4>41</i4></value>
            </param>
        </params>
    </methodCall>

     XML-RPC 协议简单、功能够用,各种语言的实现都有。它的使用也很广泛,如 WordPress 的 XML-RPC Api,搜索引擎的 ping 服务等等。JavaScript 中,也有现成的库支持以这种方式进行数据交互,能很好的支持已有的 XML-RPC 服务。不过,我个人觉得 XML 结构还是过于臃肿,一般场景用 JSON 会更灵活方便。

      相比之下,get方式的数据提交方式(编码方式)只有一种,就是application/x-www-form-urlencoding

    MIME

    "Multipurpose Internet Mail Extensions"多功能Internet邮件扩充服务,它是一种多用途网际邮件扩充协议。

    1.作用

    服务器会将它们发送的多媒体数据的类型告诉浏览器,而通知手段就是说明该多媒体的MIME类型,从而让浏览器知道接受到的信息哪些是MP3,哪些是Shockwave文件等等。

    服务器将MIME标识符放入传送的数据中来告诉浏览器使用哪个插件读取相关文件

    2.通用格式

    type/subtype

     

    3.细分

     

    类型描述典型示例
    text 表明文件是普通文本,理论上是可读的语言 text/plaintext/htmltext/css, text/javascript
    image 表明是某种图像。不包括视频,但是动态图(比如动态gif)也使用image类型 image/gifimage/pngimage/jpegimage/bmpimage/webp
    audio 表明是某种音频文件 audio/midiaudio/mpeg, audio/webm, audio/ogg, audio/wav
    video 表明是某种视频文件 video/webmvideo/ogg
    application 表明是某种二进制数据

    application/octet-streamapplication/pkcs12application/vnd.mspowerpointapplication/xhtml+xmlapplication/xml,  application/pdf,

    application/json

    对于text文件类型若没有特定的subtype,就使用 text/plain。类似的,二进制文件没有特定或已知的 subtype,即使用 application/octet-stream

  • 相关阅读:
    hdu 5224 Tom and paper 水题
    2015 UESTC 搜索专题N题 韩爷的梦 hash
    2015 UESTC 搜索专题M题 Palindromic String 马拉车算法
    2015 UESTC 搜索专题K题 秋实大哥の恋爱物语 kmp
    2015 UESTC 搜索专题J题 全都是秋实大哥 kmp
    2015 UESTC 搜索专题F题 Eight Puzzle 爆搜
    2015 UESTC 搜索专题E题 吴队长征婚 爆搜
    2015 UESTC 搜索专题D题 基爷的中位数 二分
    2015 UESTC 搜索专题C题 基爷与加法等式 爆搜DFS
    2015 UESTC 搜索专题B题 邱老师降临小行星 记忆化搜索
  • 原文地址:https://www.cnblogs.com/ygunoil/p/12069374.html
Copyright © 2011-2022 走看看