最近在搞apache开发,所以不得不涉及到HTTP协议,其中提交请求有两种常用方法:POST和GET。这两种方法有什么区别呢?
HTTP协议定义了与服务器交互的四种方法:PUT,DELETE,GET,POST,分别对应增删查改。所以大家可以看到,GET是用来查资料,而POST则可以更改资料。比如留言板或者回帖等肯定是用的POST方法,因为这更改了这个页面的信息,而一般的浏览网页默认是用的GET方法。这是GET和POST方法最本质的区别。
然而,现实中很少有人按照HTTP规范去做,PUT和DELETE方法几乎没用到过,但是随着网络的发展,越来越多的人认识到规范的重要性,也慢慢开始支持这种规范了。
现在我们来看一下HTTP定义的GET和POST格式。
HTTP协议的请求格式:
request line
header
blank line
request body
第一行必须是request line,告诉服务器请求类型(GET或者POST),请求资源和HTTP的版本。紧接着下一行是首部,告诉浏览器一些附加信息,比如支持的字符编码是什么,代理是什么,使用的什么浏览器等等。首部后面一行必须是空行,再下一行是请求体,请求体一般用于POST方法。下面来举一下实际的例子。
GET方法:
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive
blank line
第一行是request line,告诉服务器这是GET方法,请求的资源是/books/?sex=man&name=Professional,HTTP版本是1.1,GET,资源和HTTP版本之间都有空格。
首部中有主机名:www.wrox.com,用户代理 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1 等内容,最后一行是空白行,而请求体是空的。这就是GET方法的格式。GET方法的request line中提交的资源中,用?来划分URL和传输的数据,而用&来连接多个参数。比如这个例子中URL是www.wrox.com/books/,而参数是sex=man和name=Professional。如果传输的数据是英文字母或者数字,那么就原文输出,如果是空格,则转换为+,如果是中文或其他字符,则把字符串用BASE64加密,转换成%E4%BD等等,其中%号后面的是字符的ASCII的16进制表示。
如同大家看到的,GET方法所请求的资源等等都会在request line中出现,这样就有一些威胁和限制:
GET方法将请求的资源也就是URL和传输的数据都放在了request line,这样浏览器的地址栏中都能够看到,所以不安全,比如你登陆的时候用的GET方法,那么你的用户名和密码等参数会在提交页面的地址栏中被截获到。而且浏览器一般对地址栏的长度有限制,比如说最多256个字符,那么用GET方法传输数据的话就会有大小限制。
再来看POST方法:
POST / HTTP/1.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive
此处空一行
name=Professional%20Ajax&publisher=Wiley
可以看到,request line中只有请求方法(POST),请求URL /(根目录),HTTP版本1.1,首部中是一些附加信息,与GET方法中的首部差不多。首部后面是空行,然后是request body name=Professional%20Ajax&publisher=Wiley 。POST方法相当于把GET方法中request line中的传输的数据放到了request body中,而request body中的数据是不能显示看到的,所以从这方面来说POST方法要比GET方法安全。而且request body不限制大小,也就是说用POST方法可以传送大量的数据。
有了以上对GET和POST方法的了解,我们心里就清楚很多了吧。呵呵,下面提供几个GET和POST方法的请求和应答头部,有兴趣的可以看一下:
HTTP协议的响应格式:
status line
header
blank line
response body
比如下面的响应例子:
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122
空一行
<html>
<head><title>Wrox Homepage</title></head>
<body>
<!– body goes here –>
</body></html>
status line是 HTTP/1.1 200 OK ,告诉客户端请求成功,200就代表请求成功,返回请求数据。首部header的意思大家也能够看明白,header后面空一行,之后就是response body,这是一个html页面。
常用的状态码含义:
200 (OK): 找到了该资源,并且一切正常。
◆304 (NOT MODIFIED): 该资源在上次请求之后没有任何修改。这通常用于浏览器的缓存机制。
◆401 (UNAUTHORIZED): 客户端无权访问该资源。这通常会使得浏览器要求用户输入用户名和密码,以登录到服务器。
◆403 (FORBIDDEN): 客户端未能获得授权。这通常是在401之后输入了不正确的用户名或密码。
◆404 (NOT FOUND): 在指定的位置不存在所申请的资源。
好了,HTTP的请求和应答都有所了解之后我们来看一下几个例子。
GET方法:
请求:
GET /DEMOWebServices2.8/Service.asmx/CancelOrder?UserID=string&PWD=string&OrderConfirmation=string HTTP/1.1
Host: api.efxnow.com
应答:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
空一行
<?xml version=”1.0” encoding=”utf-8”?>
<objPlaceOrderResponse xmlns=”https://api.efxnow.com/webservices2.3">
<Success>boolean</Success>
<ErrorDescription>string</ErrorDescription>
<ErrorNumber>int</ErrorNumber>
<CustomerOrderReference>long</CustomerOrderReference>
<OrderConfirmation>string</OrderConfirmation>
<CustomerDealRef>string</CustomerDealRef>
</objPlaceOrderResponse>
可以看到请求一个资源后,应答时会说明内容类型(Content-Type),说明是text/xml类型的。
下面是POST方法:
请求:
POST /DEMOWebServices2.8/Service.asmx/CancelOrder HTTP/1.1
Host: api.efxnow.com
Content-Type: application/x-www-form-urlencoded
Content-Length: length
空一行
UserID=string&PWD=string&OrderConfirmation=string
应答:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
空一行
<?xml version=”1.0” encoding=”utf-8”?>
<objPlaceOrderResponse xmlns=”https://api.efxnow.com/webservices2.3">
<Success>boolean</Success>
<ErrorDescription>string</ErrorDescription>
<ErrorNumber>int</ErrorNumber>
<CustomerOrderReference>long</CustomerOrderReference>
<OrderConfirmation>string</OrderConfirmation>
<CustomerDealRef>string</CustomerDealRef>
</objPlaceOrderResponse>
好了,POST和GET方法的区别就介绍到这里。