AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML)

 Ajax技术出现的意义:

  向服务器请求额外的数据而无序卸载页面,带来更好的用户体验,页面无刷新技术。

1、Ajax的核心是XMLHttpRequest对象(简称XHR),创建XHR对象

如下兼容处理,创建XHR对象
function createXhr(){
    if(typeof XMLHttpRequest != undefined){
        return new XMLHttpRequest();//使用XMLHttpRequest构造函数来创建XHR对象,适用于IE7及以上版本,如果兼容到IE7,下边就可以省略了。
    }else if(typeof ActiveXObject != undefined){
        //适合IE7之前的版本 
        if(typeof arguments.callee.activeXString != "string"){ 
            var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML.XMLHttp"];
            for(var i = 0,len=versions.length;i<len;i++){
                try{ 
                    var xhr = new ActiveXObject(versions[i]); 
                    arguments.callee.activeXString = versions[i]; 
                    return xhr; 
                }catch (ex){ 
                    //跳过 
                } 
            }
        }
        return new ActiveXObject(arguments.callee.activeXString); 
    }else{ 
        throw new Error("No XHR object available."); 
    }; 
}
var xhr = new createXhr();
xhr;

结果如下:

2、XHR的方法

1、open()方法

//客户端:启动一个请求,以备发送
xhr.open("get","example.php",false);

传入三个参数:
第一个参数:请求的方法,get||post||delete;
第二个参数:请求的地址,相对与当前页面的路径;
第三个参数:是否异步?true表示异步||false 表示同步,一般情况下都是选择异步。

2、send()方法

//客户端:发送请求
xhr.send(null);

接收一个参数,作为请求的主体发送的数据(序列化后的data)。如果不需要传数据就必须传入 null。

调用send()之后,请求就会被分派到服务器。

3、服务器响应

服务器响应的数据会自动填充XHR对象的属性,相关的属性简介如下:

responseText:作为相应主体被返回的文本。
responseXML:如果响应的数据的内容类型是text/xml或者application/xml,那么这个属性就会保存响应数据的XML DOM文档
status:响应的HTTP状态。
statusText:HTTP状态的说明。

在客户端接受到服务器的响应之后:

首先要检查status属性,以确定响应是否已经成功的返回了。

  状态码200:HTTP请求成功,此时responseText属性内容已就绪,(在内容类型正确的情况下,responseXML也是可以访问的了)。

  状态码304:请求的内容在服务器端没有改变,可以直接使用浏览器端的缓存的版本,当然请求也是成功的。

正确的处理响应的函数如下:这里是同步发送时的处理(函数顺序执行),直接通过status来进行判断是否成功

var xhr = new createXhr();
xhr.open("get","example.php",false);//同步发送,需要等到接收成功之后js才能继续向下执行。
xhr .send(null);

if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
    console.log(xhr.responseText);
} else {
    console.log("Request was unsuccessful:" + xhr.status);
}

响应的主题都会保存到responseText属性中,而对于非XML数据,responseXML属性的值将为 null。

对于异步发送的请求(true),可以通过检测XHR对象的readyState属性,该属性表示响应活动的当前活动阶段。

该属性有如下的取值:

  0:未初始化。尚未调用open()方法。

  1:启动。调用了open(),但是没有调用send()。

  2:发送。已经调用了send()方法,但是还没有接收到响应。

  3:接收。接受到部分响应。

  4:完成。接收到了全部的响应。

在请求状态改变的时候会触发readystatechange事件,可以利用这个事件来检测每次状态变化后的readyState的值,这样就可以在响应完成的时候确定响应是否成功,并进行接下来的操作。

注意:为了保证兼容性,需要在open() 方法之前指定onreadystatechange事件处理程序。

var xhr = new createXhr();
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
            console.log(xhr.responseText);
        } else {
            console.log("Request was unsuccessful:" + xhr.status);
        }
    }
}
xhr.open("get","example.php",true);//异步发送,发送请求之后,保留状态监听事件,继续执行后边的操作,如果响应成功,4&&200||304就会执行处理函数。
xhr .send(null);

在接受到相应之前还可以调用: xhr.abort();方法来取消异步请求。

3、HTTP头部信息

头部信息非为请求头部响应头部

默认情况下,发送XHR请求的时候,默认发送下列头部信息:

Accept:浏览器能够拿来处理的内容类型。

Accept-Charset:浏览器能够现实的字符集。

Accept-Encoding:浏览器能够处理的压缩编码。

Accept-Language:浏览器当前设置的语言。

Connection:浏览器与服务器之间的连接类型。

Cookie:当前页面设置的任何cookie。

Host:发出请求的页面所在的域。

referer(将错就错,原本应该是referrer:推荐人):发出请求页面的URI。document.referrer:返回当前文档的url

User-Agent:浏览器的用户代理字符串。

可以使用的方法:

setRequestHeader("MyHeader","Myvalue");设置自定义的请求头部信息。该方法必须位于open()与send()方法之间调用才可以,准备发起请求,还未发起。

getRequestHeader("Header");获取指定名称的头部信息。

getAllRequestHeaders();获取所有的头部信息的长字符串。

4、典型的请求

1、GET请求:用于查询服务器的信息。需要的时候需要添加查询字符串。

常出现的一个问题就是查询字符串的个是有问题,所有的名称和值都需要使用encodeURIComponent() 进行编码。

如下辅助函数可以解决在url后边添加查询字符串的问题:

function addUrlParam(url,name,value){
    url += (url.indexOf("?") == -1 ? "?" : "&");
    url += encodeURIComponent(name) + "=" +encodeURIComponent(value);
    return url;
}

使用如下:

var url = "https://www.baidu.com";
url = addUrlParam(url,"name","dadaoshenyi");//"https://www.baidu.com?name=dadaoshenyi"

2、post请求:通常用于向服务器发送需要保存的数据,此时数据应该作为请求send发送的主体,发送给服务器。

请求主体是一个类似这样的字符串:name=sdfds&value1=sdfsdfds&value2=sdfsdf......;里边的字符都是经过编码的。

5、XMLHttpRequest2级

1、FormData

内置的对象:用于序列化表单以及创建与表单个是相同的数据(用于XHR传输)。最终传递给send()方法。

var  form = document.getElementById("user-info");
xhr.send(new FormData(form));

2、超时设定:timeout属性,用于表示请求在多少毫秒后就终止了。

设定超时时间,在超出时间之后检测ontimeout事件:

xhr.timeout = 1000;//设定时限为1s
xhr.ontimeout = function(){
    console.log("Request did not return in a second");
}

3、overrideMimeType()方法

6、进度事件

6个进度事件

1、loadstart:接受到响应数据的第一个字节的时候触发。

2、progress:接收响应期间一直触发。周期性的触发,也会接受到一个event对象,其target属性指向XHR对象。

3、error:请求发生错误的时候触发。

4、abort:调用abort()方法的时候触发。

5、load:  接受到完整的响应的时候触发。用以替代readystatechange事件,响应接收完毕后触发load事件。这也就是说没有再检查readyState属性了。onload事件处理程序会接受到一个event对象,其target指向XHR对象的实例。

6、loadend:通信完成时或者触发error、abort或load事件后触发。

7、跨域资源共享:CORS(Cross - Origin Resource Sharing),W3C的一个工作草案,用于突破跨域安全策略来进行资源共享

背后的原理:使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求应该是成功还是失败。受限发送一个option请求,不发送数据。确认可以跨域再发后续的请求。

跨域安全策略:同域名、同端口号、同协议。

如下:在发送请求的时候,客户端要添加一个额外的头部,包含页面请求的源信息(协议、域名和端口号),

Origin:http://www.changyangzhe.com

如果服务器认为可以接收这个请求就会回发一个相同的源信息:

Access-Control-Allow-Origin:http://www.changyangzhe.com

这个时候浏览器收到这个信息,就会发送请求,如果不匹配就会驳回请求。

跨浏览器的CORS

function createCORSRequest (method,url) {
    var xhr = createXHR();
    if ("withCredentails" in xhr) {
        xhr.open(method,url,true);
    } else if (typeof XDomainRequest != "undefined") {
        xhr = new XDomainRequest();
        xhr.open(method,url);
    } else {
        xhr = null;
    }
    return xhr;    
}

var request = createCORSRequest("get","http://www.somewhere-else.com");
if(request) {
    request.onload = function (){
    //相关代码
    }
    request.send();
}

8、其他跨域技术

1、图像Ping

原理:网页可以从任何地方加载任何图像。

2、JSONP,详细参考:说说JSON和JSONP,也许你会豁然开朗

JSONP:JSON with padding(填充式JSON或参数式JSON)

如下的样式:callback({"name":"changyangzhe"});这样的文件保存在远程的js文件中,数据就是传入的参数,调用的函数名就是callback。

由两部分组成:回调函数和数据。

回调函数:用来当响应来到的时候应该在页面中调用的函数,回调函数的名字一般在请求中指定。

数据:就是传入回调函数中的JSON数据。

实现思路:

1、前端创建script标签,设置src,添加到head中;

2、后台返回一个js变量JSONP,这个JSONP就是请求得到的JSON数据;

3、回调完成之后删除script标记。

原理:跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理。

方案:web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。

如下实例:

http://free.net/json/?callback=handleRequest

这里是在请求一个JSONP的地理定位服务。这里的回调函数的名字叫handleRequest()。

JSONP是通过动态<script>元素来使用的,使用时可以为src指定一个跨域URL,与 <img>类似,可以不受限制的从其他域加载资源。

因为JSONP是有效的js代码,所以在请求完成之后,即在JSONP响应加载到页面中以后,就会立即执行。

本地文件如下:

function handleRequest(response){
    console.log("you are at IP address " + response.ip + ",which is in" + response.city + "," + response.region_name);
}
var script = document.createElement("script");

//
提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
script.src = "http://free.net/json/?callback=handleRequest";//远程的回调函数名
document.body.insertBefore(script,document.body.firstChild);

远程的文件:

如romot.js,里边的内容如callback("ip":"123456789","city":"hangzhou");

特点:支持双向的通信

不足:不能防止其他域的恶意代码;判断JSONP请求成功与否并不容易。

3、jQuery使用jsonp的代码

//还是忍不住吐槽,虽然jquery也把jsonp归入了ajax,但其实它们真的不是一回事儿,jsonp不是ajax的一个特例
//但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。
//其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。
jQuery(document).ready(function(){
    $.ajax({
         type: "get",
         async: false,
         url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
         dataType: "jsonp",
         jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
         jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
         success: function(json){//自动帮你生成回调函数并把数据取出来供success属性方法来调用,是不是很爽呀,也就不用动态生成标签了
             alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
         },
         error: function(){
             alert('fail');
         }
     });
 });
//请求的页面生成如下一段代码,这是服务端要生成的js片段
flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});

9、ajax请求与表单提交的区别与联系

有如下几种区别:
  1. Ajax在提交、请求、接收时,都是异步进行的,网页不需要刷新;Form提交则是新建一个页面,哪怕是提交给自己本身的页面,也是需要刷新的;

  2. Ajax在提交时,是在后台新建一个请求;F却是放弃本页面,而后再请求;

  3. A必须要使用JS来实现,不启用JS的浏览器,无法完成该操作;F却是浏览器的本能,无论是否开启JS,都可以提交表单;

  4. A在提交、请求、接收时,整个过程都需要使用程序来对其数据进行处理;F提交时,却是根据你的表单结构自动完成,不需要代码干预。

典型的jquery,ajax实现,这里返回的是一个promise对象:

$.ajax({
        type: 'GET',
        async: false,
        url: 'http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx/getCountryCityByIp?callback=?',
        data:{theIpAddress:host_ip[0]},
        dataType: 'jsonp',
        jsonp: "callback",         
        success: function(msg){
            alert(JSON.stringify(msg));
        },
        error:function(XMLHttpRequest, textStatus, errorThrown){
            alert(XMLHttpRequest.status);
            alert(XMLHttpRequest.readyState);
            alert(XMLHttpRequest.responseText);
            alert(textStatus);
            alert(errorThrown);
            console.log(textStatus);
        }
    });

 

转载于:https://www.cnblogs.com/changyangzhe/p/5758952.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值