Ajax是什么?
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
Ajax的主要作用是:通过后台与服务器进行数据交换,使网页实现局部刷新。(不使用Ajax的页面,如果需要刷新数据必须整个页面刷新)
通过什么方法与后端进行交互?
通过XMLHttpRequest即可与后端进行交互。所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。
创建 XMLHttpRequest
new XMLHttpRequest();
如何向服务器发送请求?
如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法:
xmlhttp.open("GET","/getUserName",false);
xmlhttp.send();
GET 请求 (同步)
var xhr = new XMLHttpRequest();
xhr.open("GET","/demo?name=小明&age=20",false);
xhr.send();
POST 请求 (同步)
var xhr = new XMLHttpRequest();
xhr.open("POST","/demo",false);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send("{name : '小明', age : 18 }");
上述的例子中,我们使用了同步请求。但我不推荐使用 同步。但是对于一些小型的请求,也是可以的。
请记住,JavaScript 会等到服务器响应就绪才继续执行。如果服务器繁忙或缓慢,应用程序会挂起或停止。
当您使用 同步请求时,请不要编写 onreadystatechange 函数, 把代码放到 send() 语句后面即可。如 :
xmlhttp.open("GET","test1.txt",false);
xmlhttp.send();
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
异步操作
绝大多数情况下,你都会使用异步操作。只需把open函数里的false改为true,如 :
xhr.open("POST","/demo",true);
并且添加XMLHttpRequest的onreadystatechange函数即可。
每当 readyState (readyState 用与标记XMLHttpRequest的状态) 改变时,就会触发 onreadystatechange 事件。readyState 属性存有 XMLHttpRequest 的状态信息。下面是 XMLHttpRequest 对象的三个重要的属性:
在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。
所以当 readyState 等于 4 且状态为 200 时,表示响应已就绪。
下面让我们来举2个例子
GET 请求 (异步)
var xhr = new XMLHttpRequest();
xhr.open("GET","/demo?name=小明&age=18",true);
xhr.send();
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200)
{
console.log(this.responseText)
}
}
POST 请求 (异步)
var xhr = new XMLHttpRequest();
xhr.open("POST","/demo",true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send("{name : '小明', age : 18 }");
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200)
{
console.log(this.responseText)
}
}
提示 :responseText为服务器返回的数据。数据可以为json、数组、字符串等。
POST请求的setRequestHeader方法
或许你注意到,上述的post例子中,我们调用了一个setRequestHeader方法。
该方法只是XMLHttpRequest 为添加或修改HTTP头提供的一个接口方法而已, 至于里面的值则是HTTP协议的含义。当然也可以发自己的东西进去,即使IIS不能识别你的信息也不会报错。如 :
xhr.setRequestHeader('name', 'tom');
上述的例子中,CONTENT-TYPE:application/x-www-form-urlencoded含义是表示客户端提交给服务器文本内容的编码方式是URL编码。(url编码 : 键值对的方式传递数据)
当然还有其他编码方式,如:CONTENT-TYPE:multipart/form-data
那是用GET 还是 POST ?
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
1、向服务器发送大量数据(POST 没有数据量限制)
2、发送包含未知字符的用户输入时(比如用户输入密码),POST 比 GET 更稳定也更可靠 (post安全性高)
跨域请求(jsonp)
不管是post或get、异步还是同步。所有的ajax请求都要求遵守这条规则 :
发起请求的客户端 必须与 服务端在同一个域名下
否则你将会看到类似以下的报错信息
浏览器会认为你这个请求是恶意的。试想下,如果发送一个请求就能得到服务器的响应以及服务器返回的一些数据,那是不是很危险?
但是有些情况下,我们却又不得不有这种需求。那怎么办呢?
jsonp就是为了解决这个问题而诞生的。
jsonp并不是一种新技术,它只是通过HTML标签的src属性来发送请求,然后后端会返回一个回调函数给前端,我们只需要定义好后端规定的回调函数名字即可。让我们来举个简单的例子 :
var script = document.createElement('script');
script.src = 'http://localhost:8080/jsonp/?name=小明&age=20&callback=callback';
document.getElementsByTagName('head')[0].appendChild(script);
function callback(data){ //这里假设后端返回的回调函数是callbak
console.log(data)
}
当script被插到页面时,后面的src即会被执行。需要注意的是,这里并不是只要这么做就能跨域请求,服务器也需要对应的操作才可以。下面是服务器的部分代码 :(这里用node.js举例)
server.get('/jsonp', function(req,res){
var obj = req.query;
//通过src属性来发起的请求,只能以函数的形式返回。不能按正常套路来返回数据。如 :res.send( {name : obj.name, age : obj.age} ) 是错误的!
res.send( obj.callback + '(' + JSON.stringify({name : obj.name, age : obj.age}) + ')' )
res.end();
});
当服务器返回callbak函数时,则会去执行我们前端的那个callbak函数。这就是为什么我们需要写一个callbak函数在那里的原因。
设置google浏览器能跨域请求接口
复制一个google浏览器的快捷方式,然后右键-属性-快捷方式-目标
然后空一个格,输入一下代码
--disable-web-security --user-data-dir=C:\MyChromeDevUserData
若当前的路径没有MyChromeDevUserData这个文件夹,则自己手动创建。需要注意的是,必须是新版本的google
然后我在自己的服务器上,请求360的搜索接口
总结
1、使用Ajax时,需要new XMLHttpRequest(); IE5和IE6则创建ActiveXObject
2、大多数情况下,你都应该使用异步请求,使用异步请求则需要编写onreadystatechange函数以及open函数里的最后一个参数需要修改为true,并且readyState 等于 4 且状态为 200 时,表示数据已经可以使用
3、POST请求比GET请求更安全、而且POST请求能发送更多的数据给到后端
4、POST请求必须规定setRequestHeader,否则会报错
5、正常情况下,浏览器是不能跨域请求的
6、使用JSONP请求时,需要和后端商量好,回调函数的名字是什么
编写Ajax库
用过jquery的都知道,调用ajax是很简单的一件事。如 :
$.ajax({
type : 'get', //请求方式是get还是post
url : '/demo', //请求的url地址
data: { name : '小明', age : 20 }, //传递给服务端的数据
dataType : 'json', //预期服务器返回的数据格式
success : function(data){ //请求成功时执行的函数
console.log(data)
},
error : function(error){ //请求失败时执行的函数
console.log(error)
}
});
但这里并不打算介绍jquery的ajax,而是笔记自己编写的一个Ajax库,功能比较简单,能实现get、post以及jsonp的请求。有兴趣的童鞋可以了解下~ (调用方法与jQuery一样)
var $ = {
type : null,
url : null,
data : null,
dataType : null,
success : null,
error : null,
xmlhttp : null,
//ajax
ajax : function(obj){
this.init(obj);
this.formatData(this.data);
this.send();
},
//初始化数据
init : function(obj){
if (typeof obj.url == 'undefined' ) {
throw new Error( "do you write url address?" );
return;
}
this.xmlhttp = null;
this.xmlhttp = new XMLHttpRequest();
this.type = obj.type.toUpperCase() || 'GET';
this.url = obj.url;
this.data = obj.data || null;
this.dataType = obj.dataType || 'json';
this.success = obj.success || null;
this.error = obj.error || null;
},
//格式化data ( { name : '小明', age : 20 } 变成 name=小明&age=20 )
formatData : function(data){
var temp = '';
for(var i in this.data){
temp += ''+ i + '=' + this.data[i] + '&';
}
temp = temp.substr(0, temp.length-1);
this.data = temp;
},
//发送数据(都为异步发送)
send : function(){
var self = this;
if (this.dataType != 'jsonp')
{
switch(this.type)
{
case "GET":
this.url = this.url + '?' + this.data;
//xmlhttp
this.xmlhttp.open('GET', this.url, true);
this.xmlhttp.send(null);
this.xmlhttp.onreadystatechange = function()
{
if (this.readyState == 4)
{
if( this.status == 200)
{
self.onreadystatechangeSuccess(this.responseText);
}
else
{
self.error(this.statusText);
}
}
}
break;
case "POST":
this.xmlhttp.open('POST', this.url, true);
this.xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
this.xmlhttp.send(this.data);
this.xmlhttp.onreadystatechange = function(){
if (this.readyState == 4)
{
if( this.status == 200)
{
self.onreadystatechangeSuccess(this.responseText);
}
else
{
self.error(this.statusText);
}
}
}
break;
}
}
else
{
if (this.type == 'POST') {
throw new Error( "jsonp type only use GET !" );
return;
}
var script = document.createElement('script');
script.src = this.url+'?'+this.data+'&callback=$.callback'; //前面一个callback是给后端用的,后面一个callback是回调函数
document.getElementsByTagName('head')[0].appendChild(script);
}
},
//jsonp的回调函数
callback : function(data){
this.success(data);
},
//根据dataType,返回数据
onreadystatechangeSuccess : function(responseText){
switch(this.dataType)
{
case 'string':
this.success(responseText);
break;
case 'json':
this.success( eval("("+responseText+")") );
break;
}
}
}
ajax插件案例下载 :http://download.csdn.net/download/qq408896436/10216241