`
万俟辉夜
  • 浏览: 21534 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

【转载】HTTP协议与HTML表单(再谈GET与POST的区别)

阅读更多

原文地址:http://blog.csdn.net/darxin/article/details/4944225

 

 

HTTP的GET/POST方式有何区别?这是一个老生常谈的问题,但老生常谈的问题往往有一些让人误解的结论。本文将带您浅尝HTTP协议,在了解HTTP协议的同时将会展示许多被人们忽视的内容。在掌握了HTTP协议的过程中我们将自然而然地了解到GET与POST的本质区别。

 

 

HTTP请求

从使用者的角度看,一个HTTP请求起始于
用户端浏览器上输入的一个URL地址;
网页中的一个超链接;
提交一个HTML表单。
但本质上说,一个HTTP请求起始于用户端向HTTP服务器发送的一个URL请求。

一个标准的HTTP请求由以下几个部分组成

<request-line>
<headers>
<CRLF>
[<request-body><CRLF>]

在HTTP请求中,第一行是请求行(request-line),用来说明请求类型、要访问的资源(URL)以及使用的HTTP版本;
紧接着是多行头部(headers)信息,用来说明服务器要使用的附加信息;
头部信息之后是一个回车换行符(/r/n),用于标明头部信息的结束。
以上是必须内容,根据需要可在头部信息结束之后增加主体数据(request-body);
主体数据之后是一个回车换行符(/r/n),用于标明主体数据的结束。

 

需要注意的是
请求行(request-line)中的URL部分必须以application/x-www-form-urlencoded方式编码。
主体数据(request-body)的编码方式由头部(headers)信息中的Content-Type指定。
主体数据(request-body)的长度由头部(headers)信息中的Content-Length指定。

 

例如,我们可以在IE浏览器上输入下面的网址:

http://localhost:8000/hello/index.html

HTTP请求的头部信息如下:

GET /hello/index.html HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
Host: localhost:8000
Connection: Keep-Alive
Cookie: JSESSIONID=BBBA54D519F7A320A54211F0107F5EA6

 

[End]

上述信息没有request-body部分,这是以GET方式发送的HTTP请求。如果请求中需要附加主体数据,即增加request-body部分,则必须使用POST方式发送HTTP请求。HTML超链接(<a></a>)只能用GET方式提交HTTP请求,HTML表单(<form></form>)则可以使用两种方式提交HTTP请求。

 

 

HTML表单

HTML表单的使用方法如下:

  1. <form action="目标地址" method="发送方式" enctype="数据主体的编码方式">  
  2.     <!-- 各类型的表单域 -->  
  3.     <input name="NAME" value="VALUE"/>  
  4.     <textarea name="NAME">VALUE</textarea>  
  5.     <select name="NAME">  
  6.         <option value="VALUE" selected="selected"/>  
  7.     </select>  
  8. </form>  

 

表单中存在各种类型的表单域标签,如<input/>、<textarea/>及<select/>。每一种表单域标签均有NAME与VALUE两种标签属性。这两个标签属性决定了表单提交时传送的属性名及相应的值。

目标地址(URL)

action标签属性指定了表单提交的目标地址,其值可以是完整的URL。如:

<form action="http://localhost:8000/hello/checkUser.html"></form>

如果放置表单的网页与表单提交的目标地址在同一个HTTP服务器上,则目标地址可以用绝对路径表示(绝对路径相对于HTTP服务器)。绝对路径以“/”开头,包括WEB应用上下文及请求。如:

<form action="/hello/checkUser.html"></form>

如果放置表单的网页与表单提交的目标地址在同一个WEB应用上下文上,则目标地址可以用相对路径表示(相对路径相对于放置表单的网页)。相对路径不以“/”开头,不包括WEB应用上下文。如:

<form action="checkUser.html"></form>

需要注意的是,action标签属性的值必须符合URL的要求,其编码必须符合application/x-www-form-urlencoded编码规则。如下面的表单:

  1. <!-- 不符合要求的表单 -->  
  2. <form action="checkUser.html?opt=中文" method="POST">  
  3. </form>  

 

这样的表单是不符合要求的。如果其URL值存在非法字符(如中文字符),应将其进行URL Encoding处理。URL Encoding的处理方法如下:

  • 字母数字字符 "a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不变。
  • 特殊字符 "."、"-"、"*" 和 "_" 保持不变。
  • 空格字符 " " 转换为一个加号 "+"。
  • 所有其他字符都是不安全的,因此首先使用一种编码机制将它们转换为一个或多个字节。然后对每个字节用一个包含 3 个字符的字符串 "%xy" 表示,其中 xy 为该字节的两位十六进制表示形式。推荐的编码机制是 UTF-8。

将“中文”两个字符进行URL Encoding所得到的值就是“%E4%B8%AD%E6%96%87”。

所以正确的表单应该是:

  1. <!-- 符合要求的表单 -->  
  2. <form action="checkUser.html?opt=%E4%B8%AD%E6%96%87" method="POST">  
  3. </form>  

 

发送方式

method标签属性指定了表单的发送方式,发送方式只有两种:GET及POST。
当以GET方式发送表单时,发送的HTTP请求没有request-body部分,所以不需要指定enctype标签属性。

GET方式只提交表单域中的数据,action标签属性中如果存在?子句,GET方式将不予处理。如下面的表单:

[xhtml:nogutter] view plaincopy
  1. <form action="checkUser.html?opt=xxx" method="GET">  
  2.     <input type="text" name="username" value="yyy"/>  
  3.     <input type="text" name="age" value="zzz"/>  
  4.     <input type="submit" value="submit"/>  
  5. </form>  

 

表单提交时没有包括opt属性,HTTP头部信息如下:

GET /hello/checkUser.html?username=yyy&age=zzz HTTP/1.1
Referer: http://localhost:8000/hello/index.html
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
Host: localhost:8000
Connection: Keep-Alive
Cookie: JSESSIONID=BBBA54D519F7A320A54211F0107F5EA6

 

[End]

需要注意的是,以GET方式提交表单时,每个表单域的NAME与VALUE要以URL的方式提交,所以每个表单域的NAME与VALUE均要进行URL Encoding处理。这个操作通常是由用户端浏览器完成的。如下面的表单:

[xhtml:nogutter] view plaincopy
  1. <form action="checkUser.html" method="GET">  
  2.     <input type="hidden" name="opt" value="中文"/>  
  3.     <input type="text" name="username" value="yyy"/>  
  4.     <input type="text" name="age" value="zzz"/>  
  5.     <input type="submit" value="submit"/>  
  6. </form>  

其中表单域opt的VALUE是中文字符“中文”,在表单提交时,用户端浏览器会自动将其进行URL Encoding。HTTP头部信息如下:

 

GET /hello/checkUser.html?opt=%E4%B8%AD%E6%96%87&username=yyy&age=zzz HTTP/1.1
Referer: http://localhost:8000/hello/index.html
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
Host: localhost:8000
Connection: Keep-Alive
Cookie: JSESSIONID=BBBA54D519F7A320A54211F0107F5EA6

 

[End]

 

当以POST方式发送表单时,表单域中的数据将作为request-body提交,action标签属性中的?子句将在request-line中得以保留。如下面的表单:

[xhtml:nogutter] view plaincopy
  1. <form action="checkUser.html?opt=xxx" method="POST">  
  2.     <input type="text" name="username" value="yyy"/>  
  3.     <input type="text" name="age" value="zzz"/>  
  4.     <input type="submit" value="submit"/>  
  5. </form>  

 

表单提交时,HTTP头部信息如下:

POST /hello/checkUser.html?opt=xxx HTTP/1.1
Referer: http://localhost:8000/hello/index.html
Accept: */*
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: localhost:8000
Content-Length: 20
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=BBBA54D519F7A320A54211F0107F5EA6

 

username=yyy&age=zzz
[End]

需要注意的是,以POST方式提交表单时,action标签属性的值必须是已经进行了URL Encoding处理之后的值,用户端浏览器不会自动处理URL中的非法字符。如下面的表单是不符合要求的:

  1. <!-- 不符合要求的表单 -->  
  2. <form action="checkUser.html?opt=中文" method="POST">  
  3.     <input type="text" name="username" value="yyy"/>  
  4.     <input type="text" name="age" value="zzz"/>  
  5.     <input type="submit" value="submit"/>  
  6. </form>  

 

正确的表单应该是:

  1. <form action="checkUser.html?opt=%E4%B8%AD%E6%96%87" method="POST">  
  2.     <input type="text" name="username" value="yyy"/>  
  3.     <input type="text" name="age" value="zzz"/>  
  4.     <input type="submit" value="submit"/>  
  5. </form>  

 

数据主体的编码方式

在HTTP请求中,request-line总是以application/x-www-form-urlencoded方式编码。enctype标签属性只对request-body起作用。也就是说只有在method="POST"的情况下,设置enctype才起作用。
设置enctype标签属性后,在HTTP请求的头部(headers)信息中会多出一行Content-Type信息,并且request-body部分将会以Content-Type指定的MIME进行编码。这些操作都是由客户端浏览器自动完成的。

 

在没有指定enctype标签属性时,表单以默认的application/x-www-form-urlencoded方式对request-body进行编码。
如果表单域中的NAME或VALUE含有非法字符(如中文字符),客户端浏览器会自动对其进行URL Encoding处理。如下面的表单:

[xhtml:nogutter] view plaincopy
  1. <form action="checkUser.html" method="POST">  
  2.     <input type="hidden" name="opt" value="中文"/>  
  3.     <input type="text" name="username" value="yyy"/>  
  4.     <input type="text" name="age" value="zzz"/>  
  5.     <inupt type="submit" value="submit"/>  
  6. </form>  

 

表单提交时,HTTP头部信息如下:

POST /hello/checkUser.html HTTP/1.1
Accept: */*
Referer: http://localhost:8000/hello/index.jsp
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: localhost:8000
Content-Length: 43
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=4EF9C5B81356481F470F3C60D9E77D94

 

opt=%E4%B8%AD%E6%96%87&username=yyy&age=zzz
[End]

 

如果表单中包含需要上传的文件数据,则在指定method="POST"的同时还要指定enctype="multipart/form-data"。如下面的表单:

[xhtml:nogutter] view plaincopy
  1. <form action="checkUser.html?opt=xxx" method="POST"   
  2.         enctype="multipart/form-data">  
  3.     <input type="text" name="username" value="yyy"/>  
  4.     <input type="text" name="age" value="zzz"/>  
  5.     <input type="file" name="file" />  
  6.     <inupt type="submit" value="submit"/>  
  7. </form>  

 

表单提交时HTTP头部信息如下:

POST /hello/checkUser.html?opt=xxx HTTP/1.1
Accept: */*
Referer: http://localhost:8000/hello/index.html
Accept-Language: zh-cn
Content-Type: multipart/form-data; boundary=---------------------------7d931c5d043e
Accept-Encoding: gzip, deflate
Host: localhost:8000
Content-Length: 382
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=6FE3D8E365DF9FE26221A32624470D24

 

-----------------------------7d931c5d043e
Content-Disposition: form-data; name="username"

 

yyy
-----------------------------7d931c5d043e
Content-Disposition: form-data; name="age"

 

zzz
-----------------------------7d931c5d043e
Content-Disposition: form-data; name="file"; filename="C:/1.txt"
Content-Type: text/plain

 

hello
-----------------------------7d931c5d043e--

 

[End] 

GET与POST的区别

HTTP请求的GET与POST方式的本质区别可以参考hyddd《浅谈HTTP中Get与Post的区别》一文中的描述,本文讲述了其中比较重要的一条,那就是数据传输的位置不同。
GET方式在request-line中传送数据;POST方式在request-line及request-body中均可以传送数据。

对网上传言的解释

传言1:GET方式对长度有限制;POST方式对长度没限制。
回答:长度限制之说一方面是HTTP客户端(如IE限定URL长度为2083字节,opera 是4050, Netscape 是8192)的限制;另一方面服务器的实现也加入了限制(如果URL长度过长,HTTP服务器会报414错误)。但HTTP协议及URL官方说明均对长度限制则没有规定。

 

传言2:GET是从服务器上获取数据;POST是向服务器传送数据。
回答:GET方式就没有向服务器传送数据?那么URL中的?子句送的是什么?不论是GET还是POST,都可以向服务器传送数据,只不过传送数据的位置不同;不论是GET还是POST,都要从服务器上获取数据,否则IE浏览器拿什么东西给我们看呢?关键的问题是
GET的主要任务是获得数据,但在获得数据前也可以向服务器提交一些数据; 
POST的主要任务是提交数据,但在提交数据之后服务器也会向用户端返回一些显示用的数据。

 

传言3:GET不安全,用户能从地址栏上看到传送的数据;POST安全,用户不能从地址栏上看到传送的数据。
回答:POST方式看不到传送的数据是因为IE浏览器做了限制。如果你通过第三方工具看到了POST方式传送的数据,你还能说POST方式是安全的吗?理论上说GET和POST方式都不安全,要不就用不着研究HTTPS了。

参考资料:

[1]. HTTP协议(http://www.ietf.org/rfc/rfc2616.txt
[2]. HTML协议官方说明(http://www.w3.org/TR/html4/
[3]. URL标准(http://www.ietf.org/rfc/rfc1738.txt
[4]. MIME标准(http://www.ietf.org/rfc/rfc2045.txt

 

 

原文地址:http://blog.csdn.net/darxin/article/details/4944225

分享到:
评论

相关推荐

    Http协议中POST和GET方法的本质区别

    HTTP中的POST和GET方法是两种最常用于网页开发的数据传输方式,它们在原理和表现形式上存在本质区别。 首先,从原理上看,GET方法通常用于获取资源信息,它通过URL来传递参数,URL全称为资源描述符,表示网络上的一...

    http协议get与post的区别

    在深入探讨HTTP协议中GET与POST请求方法的区别之前,我们首先需要理解HTTP(HyperText Transfer Protocol)的基础概念。HTTP是一种应用层协议,用于从万维网服务器传输超文本到本地浏览器的传输协议。它允许数据在...

    表单提交中get和post的区别

    例如,假设我们有一个表单,包含一个文本框,名称为“Text”,那么在get方式中,提交的URL将是“getpost.asp?Text=http://leewei.blogchina.com”。而在post方式中,表单内各个字段与其内容将被放置在HTML HEADER内...

    html页面模式get/post请求

    首先,GET和POST是HTTP协议中的两种主要请求方法。GET通常用于获取资源,它将数据附加到URL上,以查询字符串的形式传递。而POST则常用于向服务器发送数据,如表单提交,数据被包含在请求正文中,这对于传输大量或...

    C#-HTTP请求(Post,GET,表单)

    C#-HTTP请求(Post,GET,表单)

    GET与POST的区别

    "GET与POST的区别" GET和POST是HTTP协议中两种最常用的请求方法,它们都是用来从客户端向服务器端发送请求的,但它们之间有很多不同之处。 GET方法 GET方法是从服务器上获取数据的请求方法。它的主要特点是将参数...

    Web应用安全:HTTP协议GET和POST的使用区别实验.docx

    本实验旨在通过实际操作深入理解HTTP协议中POST方法的工作机制及其与GET方法的区别。实验将利用Firefox浏览器的Firebug插件以及Wireshark抓包工具进行。 **实验目的**:通过实践加深对HTTP POST方法的理解,掌握...

    VC++ HTTP Get Post请求

    在VC++编程环境中,HTTP(超文本传输协议)Get和Post请求是常见的网络通信方法,用于从或向服务器发送数据。这两个方法是Web应用程序与服务器交互的基础,理解它们的工作原理和如何在VC++中实现至关重要。 **HTTP ...

    c# http协议,实现get或post发送请求 并返回内容

    GET和POST是HTTP协议中最常用的两种请求方法。本篇将详细介绍如何在C#中利用HTTP协议实现GET和POST请求,并获取返回的内容。 首先,让我们了解GET和POST的基本概念: 1. GET:GET请求是最常见的HTTP方法,用于从...

    java HttpClient 发送GET请求和带有表单参数的POST请求教程例子

    ### Java HttpClient 发送GET请求和带有表单参数的POST请求详解 #### 一、概述 在Java编程中,处理HTTP请求是一项常见的需求,特别是在与Web服务进行交互时。Apache HttpClient库提供了一种强大的方法来执行HTTP...

    浅析Get与Post的区别

    浅析Get与Post的区别 Get和Post是两种常用的表单提交方式,在Web开发中经常被使用。但是,很多人并不了解这两种方式的区别,导致在实际开发中出现问题。本文将详细阐述Get和Post的区别,以便读者更好地理解和使用这...

    C# http Get/POST请求封装类

    GET和POST是HTTP协议中最常见的两种请求方法,分别用于获取资源和提交数据。本文将详细讨论如何在C#中封装一个用于执行HTTP GET和POST请求的类,以及`HttpHelper.cs`文件中的关键实现。 首先,了解GET和POST的基本...

    ajax POST 与GET提交的区别

    ### AJAX POST 与 GET 提交的区别详解 #### 一、GET与POST基本概念及应用场景 在探讨AJAX中GET和POST的区别之前,我们先来了解一下这两种请求方式的基本概念。 **GET**请求通常用于获取资源信息,它将参数拼接到...

    Web应用安全:HTTP协议GET和POST的使用区别.pptx

    在Web应用安全中,了解HTTP协议的GET和POST方法的使用差异至关重要。GET和POST是HTTP协议中最基本的两种请求方法,它们各自有着特定的用途和限制。 1. GET方法: GET方法通常用于从服务器获取资源。在URL中,查询...

    Http post\get 发送表单

    在IT行业中,HTTP(超文本传输协议)是网络上应用最为广泛的一种协议,它是互联网上应用最为广泛的一种网络协议,负责客户端(浏览器)与服务器之间的通信。本文将深入讲解HTTP中的POST和GET方法,以及如何封装HTTP...

    HttpTest Get与Post示例

    一、HTTP GET与POST的区别 1. GET:主要用来获取资源,它是幂等的,即多次执行同一个GET请求,结果是一样的。参数通过URL传递,显示在地址栏中,一般对数据量有限制,通常不超过2KB。 2. POST:常用于提交数据,可以...

    Http协议自测工具(Get or Post)

    Get和Post是HTTP协议中最常见的两种请求方法。 Get请求是最基本的HTTP请求方式,通常用于获取(查询)资源。它在URL中直接附带参数,所有数据都在URL中可见,因此对于敏感信息不安全。同时,由于URL长度有限制,Get...

    IE插件直接观察http协议执行细节捕获POST和GET方法.rar

    HTTP协议主要包含两种请求方法:GET和POST,它们在Web开发中扮演着至关重要的角色。 GET方法是HTTP协议中最常见的请求方法,主要用于获取资源。当你在浏览器中输入URL并点击“回车”时,浏览器就向服务器发送了一个...

    Http-test.rar_HTTP_HTTP协议_c++ socket http get_http post get_sock

    2. **HTTP POST**:与GET不同,POST用于向服务器提交数据,常用于表单提交或文件上传。POST请求的数据位于请求体中,不是URL的一部分,因此可以传输更多、更大或更复杂的数据。在C++中,你不仅需要构造包含POST方法...

    get、post区别

    理解GET与POST的区别对于掌握Web开发至关重要。 ### GET与POST的基本区别 #### 1. 数据传输位置 - **GET**:参数通过URL进行传递,数据附在URL之后,以问号“?”分隔URL和传输数据,并且多个参数之间用“&”符号...

Global site tag (gtag.js) - Google Analytics