什么是 HTTP?
举例:客户端(浏览器)向服务器提交 HTTP 请求;服务器向客户端返回响应。响应包含关于请求的状态信息以及可能被请求的内容。
两种 HTTP 请求方法:GET 和 POST
在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。
- GET - 从指定的资源请求数据。
- POST - 向指定的资源提交要被处理的数据
1)get是从服务器上获取数据,注意,它只是获取、查询数据,也就是说它不会修改服务器上的数据,从这点来讲,它是数据安全的(这里的安全仅仅是指该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态)。post是向服务器传送数据,可以向服务器发送修改请求,从而修改服务器的,比方说,我们要在论坛上回贴、在博客上评论,这就要用到Post了,当然它也是可以仅仅获取数据的。
补充:根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的。幂等(idempotent、idempotence)是一个数学或计算机学概念,常见于抽象代数中。
幂等有以下几种定义:
对于单目运算,如果一个运算对于在范围内的所有的一个数多次进行该运算所得的结果和进行一次该运算所得的结果是一样的,那么我们就称该运算是幂等的。比如绝对值运算就是一个例子,在实数集中,有abs(a)=abs(abs(a))。
对于双目运算,则要求当参与运算的两个值是等值的情况下,如果满足运算结果与参与运算的两个值相等,则称该运算幂等,如求两个数的最大值的函数,有在在实数集中幂等,即max(x,x) = x。
2)get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。Post 方法通过 HTTP post 机制,将表单内各字段名称与其内容放置在 HTML 表头(header)内一起传送给服务器端交由 action 属性能所指的程序处理,该程序会通过标准输入(stdin)方式,将表单的数据读出并加以处理,用户看不到这个过程。
login.action?name=hyddd&password=idontknow&verify=%E4%BD%E5%A5%BD
a,以 ? 来分隔URL和数据;
b,以& 来分隔参数;
c,字母数字字符原样发送,但空格转换为“+”号,其它符号转换为%XX,其中XX为该符号以16进制表示的ASCII(或ISO Latin-1)值。
d,如果数据是中文或其它字符,则进行BASE64编码。
4)GET提交的数据比较少,最多1024B,因为GET数据是附在URL之后的,而URL则会受到不同环境的限制的,比如说IE对其限制为2K+35。POST方式传递的数据量相对较大,它是等待服务器来读取数据,不过也有字节限制,这是为了避免对服务器用大量数据进行恶意攻击。(POST可以传送更多的数据,理论上是没有限制的,但一般也会受不同的环境,如浏览器、操作系统、服务器处理能力等限制,IIS4可支持80KB,IIS5可支持100KB)。
5)Get方式需要使用 Request.QueryString 来取得变量的值;而 Post 方式通过 Request.Form 来访问提交的内容。
6)Get方式提交数据,会带来安全问题。比如一个登陆页面,通过 Get 方式提交数据时,用户名和密码将出现在 URL 上,如果页面可以被缓存或者其他人可以访问客户这台机器,就可以从历史记录获得该用户的帐号和密码,所以表单提交建议使用 Post 方法;Post 方法提交的表单页面常见的问题是,该页面如果刷新的时候,会弹出一个对话。所以,Post的安全性要比Get高,Post的所有操作对用户来说都是不可见的,而Get方式的参数数据是明文传输的,而且使用GET的话,还可能造成Cross-site request forgery攻击。而POST数据则可以加密的,但GET的速度可能会快些。
建议:除非你肯定你提交的数据可以一次性提交,否则请尽量用 Post 方法。出于安全性考虑,建议最好使用 Post 提交数据。
注意:Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求,在FORM(表单)中,Method默认为"GET",实质上,GET和POST只是发送机制不同,并不是一个取一个发!
比较 GET与 POST
如何选择
当请求无副作用时(如进行搜索),便可使用GET方法;当请求有副作用时(如添加数据行),则用POST方法。一个比较实际的问题是:GET方法可能会产生很长的URL,或许会超过某些浏览器与服务器对URL长度的限制。
- 请求的结果有持续性的副作用,例如,数据库内添加新的数据行。
- 若使用GET方法,则表单上收集的数据可能让URL过长。
- 要传送的数据不是采用7位的ASCII编码。
- 请求是为了查找资源,HTML表单数据仅用来帮助搜索。
- 请求结果无持续性的副作用。
- 收集的数据及HTML表单内的输入字段名称的总长不超过1024个字符。
小例子-代码解析
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>对POST和GET的测试</title>
</head>
<body>
<form action="test.jsp" method="get">
用户:<input type="text" name="user" /><br/>
密码:<input type="password" name="pwd" /><br/>
<input type="submit" value="提交" />
<input type="reset" value="重置" />
</form>
</body>
</html>
【test.jsp】
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String uname = request.getParameter("user");
String upwd = request.getParameter("pwd");
out.print(uname + ", " + upwd);//输出用户名和密码
%>
</body>
</html>
【结果】
当html文件中form的method是get时:
观察上面两种方式显示结果的url地址,是不是发现了get方式中的url更长一些,而且显示出了用户名和密码,而post方式显示的url地址就是其对应地jsp文件。所以说,通过GET提交数据,用户名和密码将明文出现在URL上,①登录页面有可能被浏览器缓存②其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,非常不安全。
小例子-百度cookie
还有一个,是我们老师讲课时说到的,因为我电脑里保存收藏了很多东西,就不实际操作去参数cookie截图了。
接下来,登录我的百度账号,然后随便搜索一个东西,假如我搜个“奇葩大会”,然后我们来看一下这个URL,看我下面截图的红色部分,是不是发现原来URL中竟然包含了我搜索的内容,说明这是通过get方式来获取的,对不对。我把英文URL贴出来(注意标高亮的部分):
https://www.baidu.com/s?wd=%E5%A5%87%E8%91%A9%E5%A4%A7%E4%BC%9A&rsv_spt=1&rsv_iqid=0xf90823f300027fe3&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=23&rsv_sug1=7&rsv_sug7=101&rsv_sug2=0&inputT=12910&rsv_sug4=12912
下图的URL是:
https://www.baidu.com/s?wd=swu%20%E8%A5%BF%E5%8D%97%E5%A4%A7%E5%AD%A6&rsv_spt=1&rsv_iqid=0xaeb676c60002e0aa&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=10&rsv_sug1=8&rsv_sug7=100&rsv_t=47feRQOnuBRb7JO3LOFjsCNYYnpd6JWsb3Gbcwn4kIAP%2F7qN7%2FwHpr3rYFFdo78PKvvu&rsv_sug2=0&inputT=6209&rsv_sug4=6216&rsv_sug=1
下图的URL是:
https://www.baidu.com/s?wd=cookie&rsv_spt=1&rsv_iqid=0xcd04cfd90002a96e&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=12&rsv_sug1=7&rsv_sug7=101&rsv_t=2d8fBEzZa7cRKV%2FKI7LbsUGbcqSvfcEsJ2QpiTh2pDLvPjzj9qBxnUiH6G4eb73s9jTx&rsv_sug2=0&inputT=9904&rsv_sug4=9905
和前面提到的“3)get一般定义格式:以 ? 来分隔URL和数据;以& 来分隔参数;字母数字字符原样发送,但空格转换为“+”号,其它符号转换为%XX,其中XX为该符号以16进制表示的ASCII(或ISO Latin-1)值”是不是对上了
参考:
http://blog.youkuaiyun.com/yaojianyou/article/details/1720913/
http://www.w3school.com.cn/tags/html_ref_httpmethods.asp
http://blog.youkuaiyun.com/perny/article/details/7465243
http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html