JQuery中的load()、$.get()和$.post()详解

 jquery  JQuery中的load()、$.get()和$.post()详解已关闭评论
1月 182018
 

文章解析的比较清楚,来自: http://blog.csdn.net/csdn_yudong/article/details/52537609

load()

1.载入HTML文档 
load()方法是jQuery中最为简单和常用的Ajax方法,能载入远程HTML代码并插入DOM中。 
它的结构为:

load(url [,data][,callback])
参数名称 类型 说明
url String 请求HTML页面的URL地址
data(可选) Object 发送至服务器的key/value数据
callback(可选) Function 请求完成时的回调函数,无论请求成功或失败

首先创建一个test.html文件,用于被load()方法加载并追加到页面中。

test.html 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <div class="comment"> <h6>张三:</h6> <p class="para">沙发.</p> </div> <div class="comment"> <h6>李四:</h6> <p class="para">板凳.</p> </div> <div class="comment"> <h6>王五:</h6> <p class="para">地板.</p> </div> </body> </html> 

然后再建一个demo1.html,在上面添加两个元素:<button>用来触发Ajax事件,id为”resText”的元素用来显示追加的HTML内容。HTML代码如下:

demo1.html 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css"> * { margin:0; padding:0;} body { font-size:12px;} .comment { margin-top:10px; padding:10px; border:1px solid #ccc;background:#DDD;} .comment h6 { font-weight:700; font-size:14px;} .para { margin-top:5px; text-indent:2em;background:#DDD;} </style> <!--   引入jQuery --> <script src="https://cdn.bootcss.com/jquery/1.7.1/jquery.min.js"></script> <script language="javascript" type="text/javascript"> $(function(){ $("#send").click(function(){ $("#resText").load("test.html");
      })
  }) </script> </head> <body> <input type="button" id="send" value="Ajax获取" /> <div class="comment"> 已有评论: </div> <div id="resText" ></div> </body> </html> 

显然,load()方法完成了原本很繁琐的工作。开发人员只需要使用jQuery选择器为HTML片段指定目标位置,然后将要加载的文件的URL作为参数传递给load()方法即可。当单击按钮后,test.html页面的HTML内ring就会被加载并插入主页面<div id=”resText”></div>的元素中。

2.筛选载入的HTML文档 
上面的例子是将test.html页面中的内容都加载到id为”resText”的元素里。如果只需要加载test.html页面内的某些元素,那么可以使用load()方法的URL参数来达到目的。通过为URL参数指定选择符,就可以很方便地从加载过来的HTML文档里筛选出所需要的内容。

load()方法的URL参数的语法结构为:“url selector”。注意,URL和选择器之间有一个空格。

例如只需要加载test.html页面中class为”para”的内容,可以将demo1.html中的

$("#resText").load("test.html");

改为

$("#resText").load("test.html  .para");

3.传递方法 
load()方法的传递方式根据参数data来自动指定。如果没有参数传递,则采用GET方式传递;反之,则会自动转换为POST方法。

//无参数传递,则是GET方式
$('#resText').load('test.php',function(){
    //... });
//有参数传递,则是POST方式
$('#resText').load('test.php',{name:'rain',age:'22'},function(){
    //... });

4.回调函数 
对于必须在加载完成后才能继续的操作,load()方法提供了回调函数(callback),该函数有3个参数,分别代表请求返回的内容请求状态XMLHttpRequest对象,jQuery代码如下:

$("#resText").load("test.html",function (responseText, textStatus, XMLHttpRequest){ alert(responseText); //请求返回的内容 alert(textStatus); //请求状态:success,error alert(XMLHttpRequest); //XMLHttpRequest对象 });

在load()方法中,无论Ajax请求是否成功,只要当请求完成(complete)后,回调函数(callback)就被触发。


load()方法通常用来从Web服务器上获取静态的数据文件,然后这并不能体现Ajax的全部价值。在项目中,如果需要传递一些参数给服务器中的页面,那么可以使用$.get()或者$.post()或者$.ajax()方法。


$.get()

$.get()方法使用GET方式来进行异步请求。 
它的结构为:

$.get(url[,data][,callback][,type])
参数名称 类型 说明
url String 请求的HTML页的URL地址
data(可选) Object 发送至服务器的key/value数据会作为QueryString附加到请求URL中
callback(可选) Function 载入成功时回调函数(只有当Response的返回状态是success才调用该方法)自动将请求结果和状态传递给该方法
type(可选) String 服务器端返回内容的样式,包括xml、html、script、json、text和_default

我们用$.get()来实现评论的功能:

get1.html 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css"> * { margin:0; padding:0;} body { font-size:12px;} .comment { margin-top:10px; padding:10px; border:1px solid #ccc;background:#DDD;} .comment h6 { font-weight:700; font-size:14px;} .para { margin-top:5px; text-indent:2em;background:#DDD;} </style> <!--   引入jQuery --> <script src="../scripts/jquery.js" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ $(function(){ $("#send").click(function(){ $.get("get1.php", { 
                        username :  $("#username").val() , 
                        content :  $("#content").val()  
                    }, function (data, textStatus){ $("#resText").html(data); // 把返回的数据添加到页面上 }
            );
       })
    }) //]]> </script> </head> <body> <form id="form1" action="#"> <p>评论:</p> <p>姓名: <input type="text" name="username" id="username" /></p> <p>内容: <textarea name="content" id="content" rows="2" cols="20"></textarea></p> <p><input type="button" id="send" value="提交"/></p> </form> <div class='comment'>已有评论:</div> <div id="resText" > </div> </body> </html> 

get1.html向get1.php发送get请求,服务器端get1.php的代码如下:

<?php 
    header("Content-Type:text/html; charset=utf-8");
    echo "<div class='comment'><h6>{$_REQUEST['username']}:</h6><p class='para'>{$_REQUEST['content']}</p></div>";
?> 

由于服务器端get1.php返回的数据格式是一段HTML片段,因此并不需要经过处理就可以将新的HTML数据插入到主页面中。 
我们再来看一下get.html中的核心代码jQuery是如何完成get请求的:

$(function(){ $("#send").click(function(){ $.get("get1.php", { 
                        username :  $("#username").val() , 
                        content :  $("#content").val()  
                    }, function (data, textStatus){ $("#resText").html(data); // 把返回的数据添加到页面上 }
            );
       })
    })

我们可以看到在回调函数中,我们直接将返回回来的data(也就是HTML片段)直接在html中使用。

HTML片段实现起来只需要很少的工作量,但这种固定的数据结构并不一定能够在其他的Web应用程序中得到重用。

XML文档

服务器端是如何接收数据然后返回XML的呢? 
代码如下:

get2.php 
<?php 
    header("Content-Type:text/xml; charset=utf-8");
    echo "<?xml version='1.0' encoding='utf-8'?>".
         "<comments>".
         "<comment username='{$_REQUEST['username'] }' >".
         "<content>{$_REQUEST['content']}</content>".
         "</comment>".
         "</comments>";
?> 

注意:由于服务器端返回的数据格式是XML文档,因此需要在服务端设置Content-Type类型,代码如下:

header("Content-Type:text/xml; charset=utf-8");

对于服务器端返回的数据是XML格式的情况,我们需要对返回的数据进行处理,才能应用到HTML中,jQuery有强大的DOM处理能力,处理XML文档与处理HTML文档一样,也可以使用常规的attr()、find()、filter()以及其他方法。jQuery代码如下:

$(function(){ $("#send").click(function(){ $.get("get2.php", { 
      username :  $("#username").val() , 
      content :  $("#content").val()  
    }, function (data, textStatus){ var username = $(data).find("comment").attr("username"); var content = $(data).find("comment content").text(); var txtHtml = "<div class='comment'><h6>"+username+":</h6><p class='para'>"+content+"</p></div>";
      $("#resText").html(txtHtml); // 把返回的数据添加到页面上 },'XML');
  });
})

返回数据格式为XML文档的过程实现起来比HTML片段要稍微复杂些,但XML文档的可移植性是其他数据格式无法比拟的,因此以这种格式提供的数据的重要性将极大提高。不过,XML文档体积相对较大,与其他文件格式相比,解析和操作它们的速度要慢一些。

JSON文件 
之所以会出现这种数据格式的文件,很大程度上是因为XML文档体积大和难以解析。JSON文件和XML文档一样,也可以方便的被重用。而且,JSON文件非常简洁,也容易阅读。

服务器端是如何接收数据然后返回JSON的呢? 
代码如下:

get3.php 
<?php 
    header("Content-Type:text/html; charset=utf-8");
    echo "{ \"username\" : \"{$_REQUEST['username']}\" , \"content\" : \"{$_REQUEST['content']}\"}" ?>

JSON的格式还是比较严格的,所以格式不能写错了。 
由于服务器端返回的数据格式是JSON文件,因此需要对返回的数据进行处理之后,才可以将新的HTML数据添加到主页面中。HTML文件其他部分还是一样,要修改的地方是jQuery部分,jQuery代码如下:

$(function(){ $("#send").click(function(){ $.get("get3.php", { 
                username :  $("#username").val() , 
                content :  $("#content").val()  
            }, function (data, textStatus){ var username = data.username; var content = data.content; var txtHtml = "<div class='comment'><h6>"+username+":</h6><p class='para'>"+content+"</p></div>";
        $("#resText").html(txtHtml); // 把返回的数据添加到页面上 },"json");
       });
    })

在上面的代码中,将$.get()方法的第4个参数(type)设置为”json”来代表期待服务器返回的数据格式。

对于服务器端返回HTML片段、XML数据、JSON数据的优缺点进行分析,可以的得知在不需要与其他应用程序共享数据的时候,使用HTML片段来提供返回数据一般来说是最简单的;如果数据需要重用,那么JSON文件是不错的选择,它在性能和文件大小方面具有优势,它是Web服务器领域的“世界语”,我们推荐使用JSON。

$.post()

它与$.get()方法的结构和使用方式都相同,不过它们之间仍然有以下区别。

  • GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTPP消息的实体内容发送给Web服务器。当然,在Ajax请求中,这种区别对用户是不可见的
  • GET方式对传输的数据有大小限制(通常不能大于2KB),而使用POST方式传递的数据量要比GET方式大得多(理论上不受限制)
  • GET方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。在某种情况下,GET方式会带来严重的安全性问题,而POST方式相对来说就可以避免这些问题。
  • GET方式和POST方式传递的数据在服务器端的获取也不相同。在PHP中,GET方式的数据可以用$_GET[]获取,而POST方式可以用$_POST[]获取。两种方式都可以用$_REQUEST[]来获取。

由于POST和GET方式提交的所有数据都可以通过$_REQUEST[]来获取,因此只需要改变jQuery函数,就可以将程序在GET请求和POST请求之间切换。 
代码如下:

$(function(){ $("#send").click(function(){ $.post("post1.php", { 
      username :  $("#username").val() , 
      content :  $("#content").val()  
    }, function (data, textStatus){ $("#resText").html(data); // 把返回的数据添加到页面上 });
  })
})

load()、$.get()和$.post(),我们可以发现,$.get()和$.post()方法是jQuery中的全局函数,而在此之前讲的load()是对jQuery对象进行操作的。

使用python的urllib, urllib2, httplib 实现get,post请求数据的简单例子

 python  使用python的urllib, urllib2, httplib 实现get,post请求数据的简单例子已关闭评论
9月 132017
 



使用python的urllib, urllib2, httplib 实现get,post请求数据的简单例子 ,转自:http://blog.csdn.net/mack415858775/article/details/39696107



测试用CGI,名字为test.py,放在apache的cgi-bin目录下:

#!/usr/bin/python
import cgi
def main(): 
    print “Content-type: text/html\n”
    form = cgi.FieldStorage()
    if form.has_key(“ServiceCode”) and form[“ServiceCode”].value != “”:
        print “<h1> Hello”,form[“ServiceCode”].value,”</h1>” 
    else:   
        print “<h1> Error! Please enter first name.</h1>” 
main()

 

python发送post和get请求

get请求:

使用get方式时,请求数据直接放在url中。
方法一、
import urllib
import urllib2

url = “http://192.168.81.16/cgi-bin/python_test/test.py?ServiceCode=aaaa

req = urllib2.Request(url)
print req

res_data = urllib2.urlopen(req)
res = res_data.read()
print res

方法二、
import httplib

url = “http://192.168.81.16/cgi-bin/python_test/test.py?ServiceCode=aaaa

conn = httplib.HTTPConnection(“192.168.81.16”)
conn.request(method=”GET”,url=url) 

response = conn.getresponse()
res= response.read()
print res

post请求:

使用post方式时,数据放在data或者body中,不能放在url中,放在url中将被忽略。
方法一、
import urllib
import urllib2

test_data = {‘ServiceCode’:’aaaa’,’b’:’bbbbb’}
test_data_urlencode = urllib.urlencode(test_data)

requrl = “http://192.168.81.16/cgi-bin/python_test/test.py

req = urllib2.Request(url = requrl,data =test_data_urlencode)
print req

res_data = urllib2.urlopen(req)
res = res_data.read()
print res


方法二、
import urllib
import httplib 
test_data = {‘ServiceCode’:’aaaa’,’b’:’bbbbb’}
test_data_urlencode = urllib.urlencode(test_data)

requrl = “http://192.168.81.16/cgi-bin/python_test/test.py
headerdata = {“Host”:”192.168.81.16″}

conn = httplib.HTTPConnection(“192.168.81.16”)

conn.request(method=”POST”,url=requrl,body=test_data_urlencode,headers = headerdata) 

response = conn.getresponse()

res= response.read()

print res
对python中json的使用不清楚,所以临时使用了urllib.urlencode(test_data)方法;

 

模块urllib,urllib2,httplib的区别
        httplib实现了http和https的客户端协议,但是在python中,模块urllib和urllib2对httplib进行了更上层的封装。
 

介绍下例子中用到的函数:
1、HTTPConnection函数

httplib.HTTPConnection(host[,port[,stict[,timeout]]])
这个是构造函数,表示一次与服务器之间的交互,即请求/响应
host        标识服务器主机(服务器IP或域名)
port         默认值是80
strict        模式是False,表示无法解析服务器返回的状态行时,是否抛出BadStatusLine异常
例如:
         conn = httplib.HTTPConnection(“192.168.81.16″,80)          与服务器建立链接。

 
2、HTTPConnection.request(method,url[,body[,header]])函数
这个是向服务器发送请求
method           请求的方式,一般是post或者get,

例如:

         method=”POST”或method=”Get”
url                  请求的资源,请求的资源(页面或者CGI,我们这里是CGI)

例如:

        url=”http://192.168.81.16/cgi-bin/python_test/test.py”      请求CGI

        或者

        url=”http://192.168.81.16/python_test/test.html”                请求页面
body               需要提交到服务器的数据,可以用json,也可以用上面的格式,json需要调用json模块
headers         请求的http头headerdata = {“Host”:”192.168.81.16″}
例如:
test_data = {‘ServiceCode’:’aaaa’,’b’:’bbbbb’}
test_data_urlencode = urllib.urlencode(test_data)
requrl = “http://192.168.81.16/cgi-bin/python_test/test.py
headerdata = {“Host”:”192.168.81.16″}
conn = httplib.HTTPConnection(“192.168.81.16″,80)
conn.request(method=”POST”,url=requrl,body=test_data_urlencode,headers = headerdata)  
conn在使用完毕后,应该关闭,conn.close()


3、HTTPConnection.getresponse()函数
     这个是获取http响应,返回的对象是HTTPResponse的实例。

 


4、HTTPResponse介绍:
HTTPResponse的属性如下:
read([amt])                              获取响应消息体,amt表示从响应流中读取指定字节的数据,没有指定时,将全部数据读出;
getheader(name[,default])      获得响应的header,name是表示头域名,在没有头域名的时候,default用来指定返回值
getheaders()                           以列表的形式获得header
例如:

date=response.getheader(‘date’);
print date
resheader=”
resheader=response.getheaders();
print resheader

列形式的响应头部信息:

[(‘content-length’, ‘295’), (‘accept-ranges’, ‘bytes’), (‘server’, ‘Apache’), (‘last-modified’, ‘Sat, 31 Mar 2012 10:07:02 GMT’), (‘connection’, ‘close’), (‘etag’, ‘”e8744-127-4bc871e4fdd80″‘), (‘date’, ‘Mon, 03 Sep 2012 10:01:47 GMT’), (‘content-type’, ‘text/html’)] 

date=response.getheader(‘date’);
print date

取出响应头部的date的值。

5月 042015
 
 
如果PostMethod提交的是中文字符,需要加上相应的编码格式:  post.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");  
如果GetMethod提交的参数有中文字符,需要先转换成utf-8格式:  URLEncoder.encode("中文", "utf-8"); 
测试代码如下:
package httpclient;

import java.io.IOException;
import java.net.URLEncoder;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;

public class HttpClientTest {

	public static void main(String[] args) throws Exception{
		String url = "/xx.jsp/xxxx";
		String host = "www.xxx.cn";
		String param = "city="+URLEncoder.encode("测试", "utf-8")+"&userID=";
		HttpClient httpClient = new HttpClient();
		httpClient.getHostConfiguration().setHost(host, 80, "http");

		HttpMethod method = getMethod(url, param);
		//HttpMethod method = postMethod(url);

		httpClient.executeMethod(method);

		String response = method.getResponseBodyAsString();
		//String response = new String(method.getResponseBodyAsString().getBytes("ISO-8859-1"));
		System.out.println(response);
	}

	private static HttpMethod getMethod(String url,String param) throws IOException{
		GetMethod get = new GetMethod(url+"?"+param);
		get.releaseConnection();
		return get;
	}

	private static HttpMethod postMethod(String url) throws IOException{
		PostMethod post = new PostMethod(url);
		post.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8"); 
		NameValuePair[] param = { new NameValuePair("city","测试"),
				new NameValuePair("userID","")} ;
    	        post.setRequestBody(param);
    	        post.releaseConnection();
		return post;
	}
}

2月 192014
 

挺好的一篇文章,一起分享下:

解释代码  收藏代码

  1. POST   /uri     创建  
  2. DELETE /uri/xxx 删除   
  3. PUT    /uri/xxx 更新或创建  
  4. GET    /uri/xxx 查看  


GET操作是安全的。所谓安全是指不管进行多少次操作,资源的状态都不会改变。比如我用GET浏览文章,不管浏览多少次,那篇文章还在那,没有变化。当然,你可能说每浏览一次文章,文章的浏览数就加一,这不也改变了资源的状态么?这并不矛盾,因为这个改变不是GET操作引起的,而是用户自己设定的服务端逻辑造成的。
PUT,DELETE操作是幂等的。所谓幂等是指不管进行多少次操作,结果都一样。比如我用PUT修改一篇文章,然后在做同样的操作,每次操作后的结果并没有不同,DELETE也是一样。顺便说一句,因为GET操作是安全的,所以它自然也是幂等的。
POST操作既不是安全的,也不是幂等的,比如常见的POST重复加载问题:当我们多次发出同样的POST请求后,其结果是创建出了若干的资源。
安全和幂等的意义在于:当操作没有达到预期的目标时,我们可以不停的重试,而不会对资源产生副作用。从这个意义上说,POST操作往往是有害的,但很多时候我们还是不得不使用它。
还有一点需要注意的就是,创建操作可以使用POST,也可以使用PUT,区别在于POST 是作用在一个集合资源之上的(/uri),而PUT操作是作用在一个具体资源之上的(/uri/xxx),再通俗点说,如果URL可以在客户端确定,那么就使用PUT,如果是在服务端确定,那么就使用POST,比如说很多资源使用数据库自增主键作为标识信息,而创建的资源的标识信息到底是什么只能由服务端提供,这个时候就必须使用POST。
  
关于GET POST 的混淆
先说相同点,只有了解了相同点之后才能理解为什么会发生混淆。
两者都能向服务器发送数据,提交的“内容”[注1]的格式相同,都是
var_1=value_1&var_2=value_2&….

get 和 post 区别如字面,一个是get(获取),一个是post(发送)。

get用来告诉服务器需要获取哪些内容(uri+query),向静态页面(uri)请求则直接返回文件内容给浏览器,向一个动态页面请求时可以提供查询参数(query)以获得相应内容。

post用来向服务器提交内容,主要是为了提交,而不是为了请求内容,就是说post的初衷并不要求服务器返回内容[注2],只是提交内容让服务器处理(主要是存储或者处理之后再存储)。

get和post出现混淆是因为对提交的数据处理方法的滥用造成的,数据是无辜的。

混淆之一:
将get提交的用来查询的字段当作是存储数据存入了服务器端文件或者数据库。然后就误以为get是用来提交用于存储的数据的。

混淆之二:
编写脚本在服务器端通过处理post提交的数据并返回内容。只要有数据,就能用来进行判断,脚本怎写是程序员的事,而不在乎数据来源的形式(post、get,或者是自己预设值的常量)。这点功能上确实没问题,只是背离的其初始目的而已。

由于都是要传送数据,且数据格式相同(即使数据格式不同,只要能提取出相应数据)。使用的时候难免出现张冠李戴,将get数据用来存储、将post数据用来检索返回数据。但是二者还是有区别的(主要是根据其用途而“人为”[注3]造成的),get的长度限制在2048字节(由浏览器和服务器限制的,这是目前IE的数据,曾经是1024字节),很大程度上限制了get用来传递“存储数据”的数据的能力,所以还是老老实实用来做检索吧;post则无此限制(只是HTTP协议规范没有进行大小限制,但受限于服务器的处理能力),因此对于大的数据(一般来说需要存储的数据可能会比较大,比2048字节大)的传递有天然的优势,谁让它是 nature born post 呢。

get提交的数据是放在url里,目的是灵活的向服务其提交检索请求,可以在地址栏随时修改数据以变更需要获取的内容,比如直接修改分页的编号就跳到另外一个分页了(当然也可能是 404)。post提交的数据放在http请求的正文里,目的在于提交数据并用于服务器端的存储,而不允许用户过多的更改相应数据(主要是相对于在url 修改要麻烦很多,url的修改只要点击地址栏输入字符就可以了),除非是专门跑来编辑数据的。

花边:post和get的安全性在传输的层面上区别不大,但是采用url提交数据的get方式容易被人肉眼看到,或者出现在历史纪录里,还是可能被肉眼看到,都是一些本地的问题。

注1:我强调的是内容,至于http协议中的get和post的格式大家有兴趣就自己看看吧。
注2:get方式主要是为了获得预期内容,即uri+query相同时所得到的内容应该是相同的。而post主要是提交内容,至于是否有必要返回页面可能只是出于用户体验,比如注册时返回你的注册id,但是如果只是返回一个“您已注册成功”的相同页面(即使你post的数据不一样)也没什么好奇怪的。
注3:关于这个“人为”,不是那么贴切,get和post还是有技术层面的区别的。但是从表象上看暂且这么说吧,毕竟二者的混淆也是“人为”的。

 

HTTP POST GET 本质区别 
原理区别

一般在浏览器中输入网址访问资源都是通过GET方式;在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认为GET提交 Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE URL 全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询 资源信息,而POST一般用于更新 资源信息(个人认为这是GET和POST的本质区别,也是协议设计者的本意,其它区别都是具体表现形式的差异 )。
根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的 。
1.所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。
* 注意:这里安全的含义仅仅是指是非修改信息。
2.幂等的意味着对同一URL的多个请求应该返回同样的结果。这里我再解释一下幂等 这个概念:
幂等 (idempotent、idempotence)是一个数学或计算机学概念,常见于抽象代数中。
幂等有以下几种定义:   对于单目运算,如果一个运算对于在范围内的所有的一个数多次进行该运算所得的结果和进行一次该运算所得的结果是一样的,那么我们就称该运算是幂等的。比如绝对值运算就是一个例子,在实数集中,有abs(a) = abs(abs(a)) 。
对于双目运算,则要求当参与运算的两个值是等值的情况下,如果满足运算结果与参与运算的两个值相等,则称该运算幂等,如求两个数的最大值的函数,有在在实数集中幂等,即max(x,x) = x 。 看完上述解释后,应该可以理解GET幂等的含义了。
但在实际应用中,以上2条规定并没有这么严格。引用别人文章的例子:比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。从根本上说,如果目标是当用户打开一个链接时,他可以确信从自身的角度来看没有改变资源即可。
根据HTTP规范,POST表示可能修改变服务器上的资源的请求 。继续引用上面的例子:还是新闻以网站为例,读者对新闻发表自己的评论应该通过POST实现,因为在评论提交后站点的资源已经不同了,或者说资源被修改了。
上面大概说了一下HTTP规范中,GET和POST的一些原理性的问题。但在实际的做的时候,很多人却没有按照HTTP规范去做,导致这个问题的原因有很多,比如说:
1.很多人贪方便,更新资源时用了GET,因为用POST必须要到FORM(表单),这样会麻烦一点。
2.对资源的增,删,改,查操作,其实都可以通过GET/POST完成,不需要用到PUT和DELETE。
3.另外一个是,早期的但是Web MVC框架设计者们并没有有意识地将URL当作抽象的资源来看待和设计 。还有一个较为严重的问题是传统的Web MVC框架基本上都只支持GET和POST两种HTTP方法,而不支持PUT和DELETE方法。

转自:http://www.zhihu.com/question/19728850

HTTP协议详解

 http  HTTP协议详解已关闭评论
12月 072013
 

HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。
HTTP协议的主要特点可概括如下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

 

 

一、HTTP协议详解之URL篇

    http(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。

HTTP URL (URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息)的格式如下:
http://host[“:”port][abs_path]
http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用缺省端口80;abs_path指定请求资源的URI;如果URL中没有给出abs_path,那么当它作为请求URI时,必须以“/”的形式给出,通常这个工作浏览器自动帮我们完成。
eg:
1、输入:
www.guet.edu.cn
浏览器自动转换成:http://www.guet.edu.cn/
2、http:192.168.0.116:8080/index.jsp 

 

 

 

二、HTTP协议详解之请求篇

    http请求由三部分组成,分别是:请求行、消息报头、请求正文

1、请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:Method Request-URI HTTP-Version CRLF  
其中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。

请求方法(所有方法全为大写)有多种,各个方法的解释如下:
GET     请求获取Request-URI所标识的资源
POST    在Request-URI所标识的资源后附加新的数据
HEAD    请求获取由Request-URI所标识的资源的响应消息报头
PUT     请求服务器存储一个资源,并用Request-URI作为其标识
DELETE  请求服务器删除Request-URI所标识的资源
TRACE   请求服务器回送收到的请求信息,主要用于测试或诊断
CONNECT 保留将来使用
OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
应用举例:
GET方法:在浏览器的地址栏中输入网址的方式访问网页时,浏览器采用GET方法向服务器获取资源,eg:GET /form.html HTTP/1.1 (CRLF)

POST方法要求被请求服务器接受附在请求后面的数据,常用于提交表单。
eg:POST /reg.jsp HTTP/ (CRLF)
Accept:image/gif,image/x-xbit,… (CRLF)

HOST:www.guet.edu.cn (CRLF)
Content-Length:22 (CRLF)
Connection:Keep-Alive (CRLF)
Cache-Control:no-cache (CRLF)
(CRLF)         //该CRLF表示消息报头已经结束,在此之前为消息报头
user=jeffrey&pwd=1234  //此行以下为提交的数据

HEAD方法与GET方法几乎是一样的,对于HEAD请求的回应部分来说,它的HTTP头部中包含的信息与通过GET请求所得到的信息是相同的。利用这个方法,不必传输整个资源内容,就可以得到Request-URI所标识的资源的信息。该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新。
2、请求报头后述
3、请求正文(略) 

 

三、HTTP协议详解之响应篇

    在接收和解释请求消息后,服务器返回一个HTTP响应消息。

HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文
1、状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
常见状态代码、状态描述、说明:
200 OK      //客户端请求成功
400 Bad Request  //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报                 //头域一起使用 
403 Forbidden  //服务器收到请求,但是拒绝提供服务
404 Not Found  //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable  //服务器当前不能处理客户端的请求,一段时间后,                         //可能恢复正常
eg:HTTP/1.1 200 OK (CRLF)

2、响应报头后述

3、响应正文就是服务器返回的资源的内容 

 

四、HTTP协议详解之消息报头篇

    HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成。

HTTP消息报头包括普通报头、请求报头、响应报头、实体报头。
每一个报头域都是由名字+“:”+空格+值 组成,消息报头域的名字是大小写无关的。

1、普通报头
在普通报头中,有少数报头域用于所有的请求和响应消息,但并不用于被传输的实体,只用于传输的消息。
eg:
Cache-Control   用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制),HTTP1.0使用的类似的报头域为Pragma。
请求时的缓存指令包括:no-cache(用于指示请求或响应消息不能缓存)、no-store、max-age、max-stale、min-fresh、only-if-cached;
响应时的缓存指令包括:public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage.
eg:为了指示IE浏览器(客户端)不要缓存页面,服务器端的JSP程序可以编写如下:response.sehHeader(“Cache-Control”,”no-cache”);
//response.setHeader(“Pragma”,”no-cache”);作用相当于上述代码,通常两者//合用
这句代码将在发送的响应消息中设置普通报头域:Cache-Control:no-cache


Date普通报头域表示消息产生的日期和时间

Connection普通报头域允许发送指定连接的选项。例如指定连接是连续,或者指定“close”选项,通知服务器,在响应完成后,关闭连接

2、请求报头
请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。
常用的请求报头
Accept
Accept请求报头域用于指定客户端接受哪些类型的信息。eg:Accept:image/gif,表明客户端希望接受GIF图象格式的资源;Accept:text/html,表明客户端希望接受html文本。
Accept-Charset
Accept-Charset请求报头域用于指定客户端接受的字符集。eg:Accept-Charset:iso-8859-1,gb2312.如果在请求消息中没有设置这个域,缺省是任何字符集都可以接受。
Accept-Encoding
Accept-Encoding请求报头域类似于Accept,但是它是用于指定可接受的内容编码。eg:Accept-Encoding:gzip.deflate.如果请求消息中没有设置这个域服务器假定客户端对各种内容编码都可以接受。
Accept-Language
Accept-Language请求报头域类似于Accept,但是它是用于指定一种自然语言。eg:Accept-Language:zh-cn.如果请求消息中没有设置这个报头域,服务器假定客户端对各种语言都可以接受。
Authorization
Authorization请求报头域主要用于证明客户端有权查看某个资源。当浏览器访问一个页面时,如果收到服务器的响应代码为401(未授权),可以发送一个包含Authorization请求报头域的请求,要求服务器对其进行验证。
Host(发送请求时,该报头域是必需的)
Host请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的,eg:
我们在浏览器中输入:
http://www.guet.edu.cn/index.html
浏览器发送的请求消息中,就会包含Host请求报头域,如下:
Host:
www.guet.edu.cn
此处使用缺省端口号80,若指定了端口号,则变成:Host:www.guet.edu.cn:指定端口号
User-Agent
我们上网登陆论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本,你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息。User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。不过,这个报头域不是必需的,如果我们自己编写一个浏览器,不使用User-Agent请求报头域,那么服务器端就无法得知我们的信息了。
请求报头举例:
GET /form.html HTTP/1.1 (CRLF)
Accept:image/gif,image/x-xbitmap,image/jpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/* (CRLF)
Accept-Language:zh-cn (CRLF)
Accept-Encoding:gzip,deflate (CRLF)
If-Modified-Since:Wed,05 Jan 2007 11:21:25 GMT (CRLF)
If-None-Match:W/”80b1a4c018f3c41:8317″ (CRLF)
User-Agent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF)
Host:www.guet.edu.cn (CRLF)
Connection:Keep-Alive (CRLF)
(CRLF)

3、响应报头
响应报头允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和对Request-URI所标识的资源进行下一步访问的信息。
常用的响应报头
Location
Location响应报头域用于重定向接受者到一个新的位置。Location响应报头域常用在更换域名的时候。
Server
Server响应报头域包含了服务器用来处理请求的软件信息。与User-Agent请求报头域是相对应的。下面是
Server响应报头域的一个例子:
Server:Apache-Coyote/1.1
WWW-Authenticate
WWW-Authenticate响应报头域必须被包含在401(未授权的)响应消息中,客户端收到401响应消息时候,并发送Authorization报头域请求服务器对其进行验证时,服务端响应报头就包含该报头域。
eg:WWW-Authenticate:Basic realm=”Basic Auth Test!”  //可以看出服务器对请求资源采用的是基本验证机制。


4、实体报头
请求和响应消息都可以传送一个实体。一个实体由实体报头域和实体正文组成,但并不是说实体报头域和实体正文要在一起发送,可以只发送实体报头域。实体报头定义了关于实体正文(eg:有无实体正文)和请求所标识的资源的元信息。
常用的实体报头
Content-Encoding
Content-Encoding实体报头域被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。Content-Encoding这样用于记录文档的压缩方法,eg:Content-Encoding:gzip
Content-Language
Content-Language实体报头域描述了资源所用的自然语言。没有设置该域则认为实体内容将提供给所有的语言阅读
者。eg:Content-Language:da
Content-Length
Content-Length实体报头域用于指明实体正文的长度,以字节方式存储的十进制数字来表示。
Content-Type
Content-Type实体报头域用语指明发送给接收者的实体正文的媒体类型。eg:
Content-Type:text/html;charset=ISO-8859-1
Content-Type:text/html;charset=GB2312
Last-Modified
Last-Modified实体报头域用于指示资源的最后修改日期和时间。
Expires
Expires实体报头域给出响应过期的日期和时间。为了让代理服务器或浏览器在一段时间以后更新缓存中(再次访问曾访问过的页面时,直接从缓存中加载,缩短响应时间和降低服务器负载)的页面,我们可以使用Expires实体报头域指定页面过期的时间。eg:Expires:Thu,15 Sep 2006 16:23:12 GMT
HTTP1.1的客户端和缓存必须将其他非法的日期格式(包括0)看作已经过期。eg:为了让浏览器不要缓存页面,我们也可以利用Expires实体报头域,设置为0,jsp中程序如下:response.setDateHeader(“Expires”,”0″);

 

 

五、利用telnet观察http协议的通讯过程

    实验目的及原理:
    利用MS的telnet工具,通过手动输入http请求信息的方式,向服务器发出请求,服务器接收、解释和接受请求后,会返回一个响应,该响应会在telnet窗口上显示出来,从而从感性上加深对http协议的通讯过程的认识。

    实验步骤:

1、打开telnet
1.1 打开telnet
运行–>cmd–>telnet

1.2 打开telnet回显功能
set localecho

2、连接服务器并发送请求
2.1 open 
www.guet.edu.cn 80  //注意端口号不能省略

    HEAD /index.asp HTTP/1.0
    Host:www.guet.edu.cn
    
   /*我们可以变换请求方法,请求桂林电子主页内容,输入消息如下*/
    open 
www.guet.edu.cn 80 
   
    GET /index.asp HTTP/1.0  //请求资源的内容
    Host:www.guet.edu.cn  

2.2 open www.sina.com.cn 80  //在命令提示符号下直接输入telnet www.sina.com.cn 80
    HEAD /index.asp HTTP/1.0
    Host:www.sina.com.cn
 

3 实验结果:

3.1 请求信息2.1得到的响应是:

HTTP/1.1 200 OK                                              //请求成功
Server: Microsoft-IIS/5.0                                    //web服务器
Date: Thu,08 Mar 200707:17:51 GMT
Connection: Keep-Alive                                 
Content-Length: 23330
Content-Type: text/html
Expries: Thu,08 Mar 2007 07:16:51 GMT
Set-Cookie: ASPSESSIONIDQAQBQQQB=BEJCDGKADEDJKLKKAJEOIMMH; path=/
Cache-control: private

//资源内容省略

3.2 请求信息2.2得到的响应是:

HTTP/1.0 404 Not Found       //请求失败
Date: Thu, 08 Mar 2007 07:50:50 GMT
Server: Apache/2.0.54 <Unix>
Last-Modified: Thu, 30 Nov 2006 11:35:41 GMT
ETag: “6277a-415-e7c76980”
Accept-Ranges: bytes
X-Powered-By: mod_xlayout_jh/0.0.1vhs.markII.remix
Vary: Accept-Encoding
Content-Type: text/html
X-Cache: MISS from zjm152-78.sina.com.cn
Via: 1.0 zjm152-78.sina.com.cn:80<squid/2.6.STABLES-20061207>
X-Cache: MISS from th-143.sina.com.cn
Connection: close


失去了跟主机的连接

按任意键继续…


4 .注意事项:1、出现输入错误,则请求不会成功。
          2、报头域不分大小写。
          3、更深一步了解HTTP协议,可以查看RFC2616,在
http://www.letf.org/rfc上找到该文件。
          4、开发后台程序必须掌握http协议

 

六、HTTP协议相关技术补充

    1、基础:
    高层协议有:文件传输协议FTP、电子邮件传输协议SMTP、域名系统服务DNS、网络新闻传输协议NNTP和HTTP协议等
中介由三种:代理(Proxy)、网关(Gateway)和通道(Tunnel),一个代理根据URI的绝对格式来接受请求,重写全部或部分消息,通过 URI的标识把已格式化过的请求发送到服务器。网关是一个接收代理,作为一些其它服务器的上层,并且如果必须的话,可以把请求翻译给下层的服务器协议。一 个通道作为不改变消息的两个连接之间的中继点。当通讯需要通过一个中介(例如:防火墙等)或者是中介不能识别消息的内容时,通道经常被使用。
     代理(Proxy):一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过可能的翻译在内部或经过传递到其它的 服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处 理没有被用户代理完成的请求。
网关(Gateway):一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。
  网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非HTTP系统中的资源。
    通道(Tunnel):是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继 的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时通道被经常使用。

2、协议分析的优势—HTTP分析器检测网络攻击
以模块化的方式对高层协议进行分析处理,将是未来入侵检测的方向。
HTTP及其代理的常用端口80、3128和8080在network部分用port标签进行了规定
3、HTTP协议Content Lenth限制漏洞导致拒绝服务攻击
使用POST方法时,可以设置ContentLenth来定义需要传送的数据长度,例如ContentLenth:999999999,在传送完成前,内 存不会释放,攻击者可以利用这个缺陷,连续向WEB服务器发送垃圾数据直至WEB服务器内存耗尽。这种攻击方法基本不会留下痕迹。
http://www.cnpaf.net/Class/HTTP/0532918532667330.html

4、利用HTTP协议的特性进行拒绝服务攻击的一些构思
服务器端忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之小),此时从正常客户的角度看来,服务器失去响应,这种情况我们称作:服务器端受到了SYNFlood攻击(SYN洪水攻击)。
而Smurf、TearDrop等是利用ICMP报文来Flood和IP碎片攻击的。本文用“正常连接”的方法来产生拒绝服务攻击。
19端口在早期已经有人用来做Chargen攻击了,即Chargen_Denial_of_Service,但是!他们用的方法是在两台Chargen 服务器之间产生UDP连接,让服务器处理过多信息而DOWN掉,那么,干掉一台WEB服务器的条件就必须有2个:1.有Chargen服务2.有HTTP 服务
方法:攻击者伪造源IP给N台Chargen发送连接请求(Connect),Chargen接收到连接后就会返回每秒72字节的字符流(实际上根据网络实际情况,这个速度更快)给服务器。

5、Http指纹识别技术
   Http指纹识别的原理大致上也是相同的:记录不同服务器对Http协议执行中的微小差别进行识别.Http指纹识别比TCP/IP堆栈指纹识别复杂许 多,理由是定制Http服务器的配置文件、增加插件或组件使得更改Http的响应信息变的很容易,这样使得识别变的困难;然而定制TCP/IP堆栈的行为 需要对核心层进行修改,所以就容易识别.
      要让服务器返回不同的Banner信息的设置是很简单的,象Apache这样的开放源代码的Http服务器,用户可以在源代码里修改Banner信息,然 后重起Http服务就生效了;对于没有公开源代码的Http服务器比如微软的IIS或者是Netscape,可以在存放Banner信息的Dll文件中修 改,相关的文章有讨论的,这里不再赘述,当然这样的修改的效果还是不错的.另外一种模糊Banner信息的方法是使用插件。
常用测试请求:
1:HEAD/Http/1.0发送基本的Http请求
2:DELETE/Http/1.0发送那些不被允许的请求,比如Delete请求
3:GET/Http/3.0发送一个非法版本的Http协议请求
4:GET/JUNK/1.0发送一个不正确规格的Http协议请求
Http指纹识别工具Httprint,它通过运用统计学原理,组合模糊的逻辑学技术,能很有效的确定Http服务器的类型.它可以被用来收集和分析不同Http服务器产生的签名。

6、其他:为了提高用户使用浏览器时的性能,现代浏览器还支持并发的访问方式,浏览一个网页时同时建立多个连接,以迅速获得一个网页上的多个图标,这样能更快速完成整个网页的传输。
HTTP1.1中提供了这种持续连接的方式,而下一代HTTP协议:HTTP-NG更增加了有关会话控制、丰富的内容协商等方式的支持,来提供
更高效率的连接。


转自:http://blog.csdn.net/gueter/article/details/1524447