搜索
首页web前端js教程AJAX机制详解以及跨域通信

AJAX机制详解以及跨域通信

May 25, 2018 am 11:42 AM
ajax沟通

最近做的一个项目中需要ajax跨域取得数据,中间出了点小差错,于是把ajax复习一下,记录下来关于跨域的问题的要点,分享给大家

1.Ajax

1.1.Ajax简介
  Ajax简介这一部分我们主要是谈一下ajax的起源,ajax是什么?因为这些是跟技术无关的。所以,大多细节都是一笔带过。

  Ajax的起源?

  Ajax一词源于2005年 Jesse James Garrett发表的一篇题为"Ajax:A new Approach to Web Applications".他在这篇文       章中介绍了一种新技术,用他的话说,就是Ajax :Asynchronous JavaScript +XML的缩写。

  Ajax是什么?

  这种新技术的主要目的就是为了使前端网页能够向服务器请求额外的数据而不需要卸载页面。自从这种技术出现以后,微软率先引入XHRt对象(ajax能够实现的核心对象),然后其他浏览器相继实现这种技术。总而言之,ajax就是一种能异步通信的技术。

1.2.Ajax的核心对象---XMLHttpRequest
  因为IE5是最先引入这个XHR对象的,当时并没有事实上的标准。在IE中有三种不同的XHR对象版本:MSXML2.XMLHttp,MSXML2.XMLHttp.3.0和MSXML2.XMLHttp.6.0;

根据这三种版本号,在IE中创建一个XHR对象如下:

function createXHR() { //IE7之前的版本通过这种方式
  var versions = [
    'MSXML2.XMLHttp',
    'MSXML2.XMLHttp.3.0',
    'MSXML2.XMLHttp.6.0'
  ];
  var xhr = null;
  for (var item in versions) {
    try {
      xhr = new ActiveXObject(item); //若不存在该版本,可能会出错
      if (xhr) break;
    } catch (e) {
      //一般对这种错误不做处理
    }
  }
  return xhr;
}

在IE引入这个对象之后,其他浏览器厂商也相继跟随,这时候XHR对象成为事实上的标准!

跨浏览器创建XHR对象;

function createXHttpRequest() {
  if (typeof XMLHttpRequest !== 'undefined') { //不要用 if(XMLHttpRequest){}这种形式,
    return new XMLHttpRequest();              //如果是这种形式在找不到XMLHttpRequest函数的情况下,会报错。
} else if (typeof ActiveXObject !== 'undefined') { 
         return createXHR(); //用到刚才我们创建的函数 
  } else { throw new Error('不能创建XMLHttpRequest对象'); } }

1.2.XMLHttpRequest的用法
XMLHttpRequest对象的函数有6个:

open("method",url,boolean);
              //该方法的三个参数,分别为----提交方式"get"或者"post"等 
                //&& url是相对于执行代码的当前页面的路径(使用绝对路径是允许的)&&是否异步 
send();    
           //这个方法接收一个参数,这个参数是作为请求主体发送的数据, 
           //说明: 如果有参数,请使用post方式提交 使用方式如下,send("user="+username+"&pwd="+password);
           //如果没有参数,为了兼容性考虑,必须在参数中传入null,即send(null);该方式使用get方式提交

abort();       //取消当前响应,关闭连接并且结束任何未决的网络活动。

          //这个方法把 XMLHttpRequest 对象重置为 readyState 为 0 的状态,并且取消所有未决             //的网络活动。例如,如果请求用了太长时间,而且响应不再必要的时候,可以调用这个方法。

getResponseHeader()   

          //返回指定的 HTTP 响应头部的值。其参数是要返回的 HTTP 响应头部的名称。可以使用任             //何大小写来制定这个头部名字,和响应头部的比较是不区分大小写的。

          //该方法的返回值是指定的 HTTP 响应头部的值,如果没有接收到这个头部或者 readyStat             //e 小于 3 则为空字符串。如果接收到多个有指定名称的头部,这个头部的值被连接起来并             //返回,使用逗号和空格分隔开各个头部的值。

getAllResponseHeaders()       

          //把 HTTP 响应头部作为未解析的字符串返回。

          //如果 readyState 小于 3,这个方法返回 null。否则,它返回服务器发送的所有 HTTP 响应的

          //头部。头部作为单个的字符串返回,一行一个头部。每行用换行符 "\r\n" 隔开。

setRequestHeader()

         //向一个打开但未发送的请求设置或添加一个 HTTP 请求。

  XMLHttpRequest对象的属性有5个:

属性 描述
responseText 作为响应主题被返回的文本
responseXML 如果相响应的是text/html或者application/xml类型的话,这个属性将保存着响应的XML文档
status http的响应状态码
statusText http状态的说明
readyState XMLHttpRequest对象的状态位 0 1 2 3 4 分别表示5种状态
timeout 设置超时时间,单位是ms.目前只有IE8+支持---尚未标准化(不推荐使用)

  XMLHttpRequest对象的事件属性onReadyStateChange:-----所有浏览器兼容

  该属性监听的是  XMLHttpRequest对象的readyState属性的变化:

  readyState的变化分别对应如下状态:

  0:尚未初始化。未调用open()之前

  1:启动。调用open()之后,但是未调用send();

  2:发送。调用send()但是尚未得到响应。

  3:正在接收数据。刚接收到响应数据开始到接收完成之前。

  4: 完成。数据接收完成。

xhr.onreadystatechange = function () {
 if (xhr.readyState == 4) {
  if (xhr.status >= 200 && xhr.status <== 300 || xhr.status == 304) {
   alert(xhr.responseText);
   //处理接收的数据
  } else {
   //请求失败,未得到响应数据
  }
 }
}; //补充说明:注册事件必须发生在send()以前
XMLHttpRequest对象的事件属性ontimeout -----仅限IE8+,不过最新的主流高版本浏览器也已经实现(不推荐使用)
xhr.timeout=1000;//一秒钟
xhr.ontimeout=functon(){  //处理代码  ......}

  这种使用方式有个问题需要注意,就是在超时之后,在接收到数据后仍然会触发onreadystatechange事件,如果在处理onreadychange事件时访问xhr.status属性,会出错。所以我们在访问该属性时需要做一下try{}catch处理。但是,因为这个属性暂不兼容,所有我们就不重点讲了。

XMLHttpRequest对象的事件属性onload onerror onloadstar onbort onprogress:

                                                                                                   -----非IE浏览器和IE 10+已实现

       onload在IE8以上可以实现,大部分事件根据readySate变化均可以实现,以上事件只不过是方便使用而已。

  onload和onprogress 这两种事件分别对应着readyState=4和readyState=3的情况,使用方式分别如下:

   xhr.onload= function (event) {
      //event只包含一个属性 event.target=xhr;使用方式只是在readyState=4时差不多..
    }
   xhr.onprogress=function(event){
     //event除了包含event.target=xhr之外,还包含三种属性
     //lengthComputale(进度信息是否可用),position(已接受字节数)和totalSize(总字节数).
     
   }


补充:有些事件均可以根据readyState的状态进行模拟。只有有的浏览器进行了方便化处理而已。  

3.单向跨域技术 ---CORS
 今天我们这里讲的是客户端网页向不在同一个域的服务器请求数据..客户端在收到返回的数据时时,用回调函数处理数据。

即:

 1. 客户端向域外服务器请求数据

 2.服务器得到响应后向客户端发送数据。

 3.客户端根据返回的数据执行回调函数.

 我知道不同域下的iframe也可以进行通信,而且这也是一种跨域通信技术。但是,这种iframe页面之间的双向通信,我们在下一个专题里面讲解,今天主要讲的是单向通信。

3.1.CORS跨域请求的原理
在用xhr(XMLHttpRequest)对象或者xdr(XDomainRequest)对象,发送域外请求时,大概的实现原理如下图:

 3.2.IE中CORS技术的实现
 IE8引入了一个XDR类型,这个类型与XHR基本类似,但是其能实现安全可靠地跨域通信。

 XHD的特点:

 1.cookie不会随请求发送,也不会随响应返回。

 2.只能设置请求头部中的Content-Type片段。

 3.不能访问响应头部信息。

 4.只是支持get和post请求。

 XDR支持onload和onerror事件属性,且其使用方式和XHR基本一致,不过其open()只接收两个参数,默认是异步的。

var xdr = new XDomainRequest();
xdr.onload = function () {
 //处理xdr.responseText
}
xdr.onerror = function () {
};
xdr.open(&#39;get&#39;, &#39;绝对url&#39;);
xhr.send(null);

3.3.跨浏览器的CORS技术实现

在标准浏览器中XHR对象就已经可以自动实现跨域请求,但是XHR和XDR的不同之处:

1.XHR可以在设置 withCredentials =true时,浏览器会把cookie发送给服务器,服务器此时通过设置头部Access-Control-Allow-Credentials:true时来响应。如果,服务器不设置这个属性,则浏览器会触发onerror事件。

2.在回调函数中可以访问status和statusText属性,而且支持同步请求。

 以下是实现跨域请求的代码:

function createCrosRequest(method, url) {
 var xhr = new XMLHttpRequest(); //IE7+
 if (&#39;withCredentials&#39; in xhr) { //IE8-IE9浏览器没有这个属性
  xhr.open(method, url, true);
 } else if (typeof XDomainRequest != &#39;undefined&#39;) {
  xhr = new XDomainRequest();  //IE
  xhr.open(method, url)
 }
 return xhr;
}
var request=CreateCrosRequest("get","url");
if(request){
 request.onload=function(){
 //处理request.responseText;
 }
 request.send(null);
}

4.单向跨域技术 ---JSONP技术

 JSONP技术比较简单,其主要原理主要是利用script标签的特性。

 script标签和image标签一样,它们都具有src属性,而且这个属性是可跨域的。

因为script标签返回的都是js代码,且该js代码会自动执行。所以,如果我们请求返回的数据也是类似一段js代码的形式,岂不是就可以实现在脚本加载完毕后自动执行。

如果我们的请求,返回的数据是 callback + '(' + json + ')'; 这种形式的数据, 那么在脚本加载完毕之后也就能自动执行callback()函数了.

4.1.客户端写法

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
    <button id="button">请求数据</button>
</body>
<script>
  window.onload=function(){
    var button=document.getElementById("ibutton");
    function callback(data){
      //处理data
    }
    button.onclick=function(){
      var script=document.createElement("script");
      script="http://www.sasd.com/json/?callbak=callback"; 
      document.body.insertBefore(script,document.body.firstChild);//加载脚本
      
    }
    
  }
</script>
</html>

   1.客户端将回调函数名写入2934a685527f5cd6bcb20a3dc28499e1脚本的url参数中。

   2.script加载的时候会发送跨域请求。

4.2.服务器端

 1.通过url得到函数名,命名为callback

 2.将请求的数据作为函数的参数格式转化json格式,命名为。

 3.将返回结果拼接为 callback+"("+json+")"; --------返回的就是填充式的数据,这段数据在脚本中会自动执行。

 4.返回数据.

 4.3.JSONP技术的缺点

 1.因为是通过url传参数,所以请求只能是get类型的。

 2.3f1c4e4b6b16bbbd69b2ee476dc4f83a目前只有onload属性事件,onerror还没有统一化,如果加载脚本出错,客户端很难得到反馈。

 3.所请求数据的站点必须是可信任的,如果返回的数据段中注入的有恶意的代码,危害较大,且难以发现。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

Django框架如何使用ajax的post方法

JQuery ajax 返回json时出现中文乱码该如何解决

如何解决JQuery ajaxSubmit提交中文乱码

以上是AJAX机制详解以及跨域通信的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JavaScript是用C编写的吗?检查证据JavaScript是用C编写的吗?检查证据Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C语言编写的。1)C语言提供了高效性能和底层控制,适合JavaScript引擎的开发。2)以V8引擎为例,其核心用C 编写,结合了C的效率和面向对象特性。3)JavaScript引擎的工作原理包括解析、编译和执行,C语言在这些过程中发挥关键作用。

JavaScript的角色:使网络交互和动态JavaScript的角色:使网络交互和动态Apr 24, 2025 am 12:12 AM

JavaScript是现代网站的核心,因为它增强了网页的交互性和动态性。1)它允许在不刷新页面的情况下改变内容,2)通过DOMAPI操作网页,3)支持复杂的交互效果如动画和拖放,4)优化性能和最佳实践提高用户体验。

C和JavaScript:连接解释C和JavaScript:连接解释Apr 23, 2025 am 12:07 AM

C 和JavaScript通过WebAssembly实现互操作性。1)C 代码编译成WebAssembly模块,引入到JavaScript环境中,增强计算能力。2)在游戏开发中,C 处理物理引擎和图形渲染,JavaScript负责游戏逻辑和用户界面。

从网站到应用程序:JavaScript的不同应用从网站到应用程序:JavaScript的不同应用Apr 22, 2025 am 12:02 AM

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。

Python vs. JavaScript:比较用例和应用程序Python vs. JavaScript:比较用例和应用程序Apr 21, 2025 am 12:01 AM

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

C/C在JavaScript口译员和编译器中的作用C/C在JavaScript口译员和编译器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在行动中:现实世界中的示例和项目JavaScript在行动中:现实世界中的示例和项目Apr 19, 2025 am 12:13 AM

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。