AJAX进阶学习二:GET 和 POST 配合表单

  • Post author:
  • Post category:其他


讲到这里首先必须要介绍一下 HTTP 协议和 GET, POST 的工作方式.

当用户在Web浏览器地址栏中输入一个带有http://前缀的URL并按下Enter后,或者在Web页面中某个以http://开头的超链接上单击鼠标,HTTP事务处理的第一个阶段–建立连接阶段就开始了.HTTP的默认端口是80.

随着连接的建立,HTTP就进入了客户向服务器发送请求的阶段.客户向服务器发送的请求是一个有特定格式的ASCII消息,其语法规则为:

< Method > < URL > < HTTP Version > <\n>

{ <Header>:<Value> <\n>}*

<\n>

{ Entity Body }

请求消息的顶端是请求行,用于指定方法,URL和HTTP协议的版本,请求行的最后是回车换行.方法有GET,POST,HEAD,PUT,DELETE等.

在请求行之后是若干个报头(Header)行.每个报头行都是由一个报头和一个取值构成的二元对,报头和取值之间以”:”分隔;报头行的最后是回车换行.常见的报头有Accept(指定MIME媒体类型),Accept_Charset(响应消息的编码方式),Accept_Encoding(响应消息的字符集),User_Agent(用户的浏览器信息)等.

在请求消息的报头行之后是一个回车换行,表明请求消息的报头部分结束.在这个\n之后是请求消息的消息实体(Entity Body).

Web服务器在收到客户请求并作出处理之后,要向客户发送应答消息.与请求消息一样,应答消息的语法规则为:

< HTTP Version> <Status Code> [<Message>]<\n>

{ <Header>:<Value> <\n> } *

<\n>

{ Entity Body }

应答消息的第一行为状态行,其中包括了HTTP版本号,状态码和对状态码进行简短解释的消息;状态行的最后是回车换行.状态码由3位数字组成,有5类:

  • 1XX 保留
  • 2XX 表示成功
  • 3XX 表示URL已经被移走
  • 4XX 表示客户错误
  • 5XX 表示服务器错误
  • 例如:415,表示不支持改媒体类型;503,表示服务器不能访问.最常见的是200,表示成功.常见的报头有:Last_Modified(最后修改时间),Content_Type(消息内容的MIME类型),Content_Length(内容长度)等.

    在报头行之后也是一个回车换行,用以表示应答消息的报头部分的结束,以及应答消息实体的开始.

    下面是一个应答消息的例子:

    HTTP/1.0 200 OK

    Date: Moday,07-Apr-97 21:13:02 GMT

    Server:NCSA/1.1

    MIME_Version:1.0

    Content_Type:text/html

    Last_Modified:Thu Dec 5 09:28:01 1996

    Coentent_Length:3107

    <HTML><HEAD><TITLE>…</HTML>

    那么 GET 和 POST 有什么区别? 区别就是一个在 URL 请求里面附带了表单参数和值, 一个是在 HTTP 请求的消息实体中. 用下面的例子可以很容易的看到同样的数据通过GET和POST来发送的区别, 发送的数据是 username=张三 :

    GET 方式, 浏览器键入 http://localhost?username=张三

    GET /?username=%E5%BC%A0%E4%B8%89 HTTP/1.1

    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*

    Accept-Language: zh-cn

    Accept-Encoding: gzip, deflate

    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)

    Host: localhost

    Connection: Keep-Alive

    POST 方式:

    POST / HTTP/1.1

    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*

    Accept-Language: zh-cn

    Content-Type: application/x-www-form-urlencoded

    Accept-Encoding: gzip, deflate

    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)

    Host: localhost

    Content-Length: 28

    Connection: Keep-Alive

    username=%E5%BC%A0%E4%B8%89

    比较一下上面的两段文字, 您会发现 GET 方式把表单内容放在前面的请求头中, 而 POST 则把这些内容放在请求的主体中了, 同时 POST 中把请求的 Content-Type 头设置为 application/x-www-form-urlencoded. 而发送的正文都是一样的, 可以这样来构造一个表单提交正文:


    encodeURIComponent(arg1)=encodeURIComponent(value1)&encodeURIComponent(arg2)=encodeURIComponent(value2)&…..

    注:

    encodeURIComponent

    返回一个包含了

    charstring

    内容的新的

    String

    对象(Unicode 格式), 所有空格、标点、重音符号以及其他非 ASCII 字符都用

    %


    xx

    编码代替,其中

    xx

    等于表示该字符的十六进制数。 例如,空格返回的是 “%20” 。 字符的值大于 255 的用

    %u


    xxxx

    格式存储。参见 JavaScript 的 encodeURIComponent() 方法.

    下面就讨论一下如何在 JavaScript 中执行一个 GET 或者 POST 请求. 如果您用过 Java, 那么您可能熟悉下列的用 java.net.URLConnection 类进行 POST 操作的代码(参考




    Java Tip 34: POSTing via Java



    ):



    URL url;

    URLConnection urlConn;

    DataOutputStream printout;


    // URL of CGI-Bin or jsp, asp script.


    url =

    new

    URL (

    "somepage"

    );


    // URL connection channel.


    urlConn = url.openConnection();


    // ......

    // No caching, we want the real thing.


    urlConn.setUseCaches (

    false

    );


    // Specify the content type.


    urlConn.setRequestProperty(

    "Content-Type"

    ,

    "application/x-www-form-urlencoded"

    );


    // Send POST output.


    printout =

    new

    DataOutputStream (urlConn.getOutputStream ());

    String content =

    "name="

    + URLEncoder.encode (

    "Buford Early"

    ) +

    "&email="

    + URLEncoder.encode (

    "buford@known-space.com"

    );

    printout.writeBytes (content);

    printout.flush ();

    printout.close ();


    以上的代码向 somepage 发送了一次 POST 请求, 数据为 name = Buford Early, email = buford@known-space.com.





    JavaScript 来执行 POST/GET 请求是同样的原理, 下面的代码展示了分别用 XMLHttpRequest 对象向 somepage 用 GET 和 POST 两种方式发送和上例相同的数据的具体过程:

    GET 方式




    var

    postContent =


    "name="

    + encodeURIComponent(

    "Buford Early"

    ) +

    "&email="

    + encodeURIComponent(

    "buford@known-space.com"

    );

    xmlhttp.open(

    "GET"

    ,

    "somepage"

    +

    "?"

    + postContent,

    true

    );

    xmlhttp.send(

    null

    );


    POST 方式




    var

    postContent =


    "name="

    + encodeURIComponent(

    "Buford Early"

    ) +

    "&email="

    + encodeURIComponent(

    "buford@known-space.com"

    );

    xmlhttp.open(

    "POST"

    ,

    "somepage"

    ,

    true

    );

    xmlhttp.setRequestHeader(

    "Content-Type"

    ,

    "application/x-www-form-urlencoded"

    );

    xmlhttp.send(postContent);

    至此希望你已经能够理解如何用 JavaScript 中的 XMLHttpRequest 对象来执行 GET/POST 操作, 剩下的工作就是您如何来构造这些提交的参数了, 最后我给出一个将现有的 form 提交代码修改为异步的 AJAX 提交的代码(注意目前作者还不知道如何让 file 上传表单域也能异步上传文件). 首先请看两个 JavaScript 函数:

    函数


    ajaxSubmitForm 将表单要提交的内容进行封装, 然后调用 ajaxSubmit 函数来执行真正的异步提交, 表单提交后所返回的结果则显示在给定的 DIV 容器中或者没有指定参数时用 DOM 对象动态生成一个 DIV 容器来显示结果并添加到页面末尾. 这样, 对原来的表单只需要改动一个地方就可以将原来的表单提交改为异步模式, 即在 form 标签里加入:

    onSubmit="ajaxSubmitForm(this);return false;"

    即可, return false 确保表单不会被浏览器同步提交. 完整的例子请看



    这里



    .