搜索
首页web前端js教程自定义ajax支持跨域组件(详细教程)

本篇文章给大家详细分析了自定义ajax支持跨域组件封装相关的知识点,对此有兴趣的朋友参考学习下。

Class.create()分析

仿prototype创建类继承

var Class = {
  create: function () {
    var c = function () {
      this.request.apply(this, arguments);
    }
    for (var i = 0, il = arguments.length, it; i < il; i++) {
      it = arguments[i];
      if (it == null) continue;
      Object.extend(c.prototype, it);
    }
    return c;
  }
};
Object.extend = function (tObj, sObj) { 
  for (var o in sObj) {
    tObj[o] = sObj[o];
  }
  return tObj;
};

ajax定义:ZIP_Ajax=Class.create();

其中create方法返回的是一个构造函数request,这里相当于var ZIP_Ajax= function(){ this.request.apply(this, arguments); }; 用对象冒充的方式在函数内部执行了一次构造的过程,相当于把构造函数任务交给了request方法,这里的this.request是ZIP_Ajax的实例的方法,而this指向的就是ZIP_Ajax的实例,apply后面的this指向的是ZIP_Ajax,最后根据new关键字将this才真正指向ZIP_Ajax类。有了类ZIP_Ajax的定义,接下来就可以定义其方法:

XMLHttpRequest详解:

XMLHttpRequest不是一项技术而是一个内置于主流浏览器内的一个可以完全访问http协议的对象。传统的http请求大部分都是基于form提交请求http,然后返回一个form。XMLHttpRequest支持同步请求的同时最大的优点就是支持异步传输接受数据,新建一个ajax请求实际就是实例化一个XMLHttpRequest对象。简单介绍一下主要事件及方法:

readystatechange事件:

当XMLHttpRequest发送一个http请求之后就会激发一个readystatechange事件,事件返回有五个值,0,1,2分别代表创建XMLHttpRequest、初始化完成XMLHttpRequest、发送了请求,3代表响应没结束(即只接收到响应头数据)4才是真正获得完整响应。

返回的status状态表示服务器返回的状态码:

常用的有200表示成功返回数据,301永久重定向,302为临时重定向(不安全)304读取的缓存数据400表示请求出现语法错误,403表示服务器拒绝请求,404表示请求网页资源不存在,405找不到指定位置服务器,408表示请求超时,500服务器内部错误,505表示服务器不支持请求的http协议版本。

200-300表示成功,300-400表示重定向,400-500表示请求内容或者格式或者请求体过大导致错误,500+表示服务器内部错误

open方法:

open接收三个参数分别是请求类型(get,post,head等)、url、同步或者异步

send方法:

当请求就绪后会触发send方法,发送的内容就是请求的数据(如果是get请求则参数为null;

请求成功之后会执行success自定义方法,其参数为返回数据;

ajax跨域:

什么是跨域?

如果两个站点www.a.com想向www.b.com请求数据就出现了因为域名不一致导致的跨域问题。即使是域名相同,如果端口不同的话也是会存在跨域问题(这种原因js是只能袖手旁观了)。判断是否跨域仅仅是通过window.location.protocol+window.location.host来判断例如http://www.baidu.com.

js解决跨域问题几种方案?

1、document.domain+iframe

对于主域相同而子域不同的请求可以使用域名+iframe作为解决办法。具体思想是假如有两个域名下的不同ab文件www.a.com/a.html

以及hi.a.com/b.html,我们可以在两个html文件中加上document.domain="a.com",之后通过在a文件中创建一个iframe去控制iframe的contentDocument,这样两个文件就可以对话了。举例如下:

www.a.com上的a.html文件中

document.domain="a.com";
  var selfFrame=document.createElement("iframe");
  selfFrame.src="http://hi.a.com/b.html";
  selfFrame.style.display="none";
  document.body.appendChild(selfFrame);
  selfFrame.onload=function(){
    var doc=selfFrame.contentDocument||selfFrame.contentWindow.document;//得到操作b.html权限
    alert(doc.getElementById("ok_b").innerHTML());//具体操作b文件中元素
  }

hi.a.com上的b.html文件中

document.domain="a.com";

问题:

1、安全性,当一个站点(hi.a.com)被攻击后,另一个站点(www.a.com)会引起安全漏洞。2、如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。

2、动态创建script(传说中jsonp方式)

浏览器默认禁止跨域访问,但不禁止在页面中引用其他域名的js文件,并且可以执行引入js文件中的方法等,根据这点我们可以通过创建script节点方法来实现完全跨域的通信。实现步骤为:

a.在请求发起方页面动态加载一个script,script的url指向接收方的后台,该地址返回的javascript方法会被发起方执行,url可以传参并仅支持get提交参数。

b.加载script脚本时候调用跨域的js方法进行回调处理(jsonp)。

举例如下:

发起方

function uploadScript(options){
  var head=document.getElementsByTagName("head")[0];
  var script=document.createElement("script");
  script.type="text/javasctipt";
  options.src += &#39;?callback=&#39; + options.callback;
  script.src=options.src;
  head.insertBefore(script,head.firstChild);
}
function callback(data){}
window.onload=function(){//调用
  uploadScript({src:"http://e.com/xxx/main.ashx",callback:callback})
}

接收方:

接收方只需要返回一个执行函数,该执行函数就是请求中的callback并赋参数。

3、使用html5的postMessage:

html5新功能有一个就是跨文档消息传输,如今大部分浏览器都已经支持并使用(包括ie8+),其支持基于web的实时消息传递并且不存在跨域问题。postMessage一般会跟iframe一起使用。

举例如下:

父页面:

<iframe id="myPost" src="http//www.a.com/main.html"></iframe>
window.onload=function(){
  document.getElementById("myPost").contentWindow.postMessage("显示我","http://www.a.com")
  //第二个参数表示确保数据发送给适合域名的文档
}
a.com/main.html页面:
window.addEventListener("message",function(event){
  if(event.origin.indexOf("a.com")>-1){
    document.getElementById("textArea").innerHTML=event.data;
  }
},false)
<body>
  <p>
    <span id="textArea"></span>
  </p>
</body>

这样在父页面加载完成后main.html页面的textArea部分就会显示"显示我"三个字

ajax方法封装code:

ZIP_Ajax.prototype={
  request:function(url options){
    this.options=options;
    if(options.method=="jsonp"){//跨域请求
      return this.jsonp();
    }
    var httpRequest=this.http();
    options=Object.extend({method: &#39;get&#39;,
      async: true},options||{});
    
    if(options.method=="get"){
      url+=(url.indexOf(&#39;?&#39;)==-1?&#39;?&#39;:&#39;&&#39;)+options.data;
      options.data=null;
    }
    httpRequest.open(options.method,url,options.async);
    if (options.method == &#39;post&#39;) {
      httpRequest.setRequestHeader(&#39;Content-type&#39;, &#39;application/x-www-form-urlencoded; charset=UTF-8&#39;);
    }
    httpRequest.onreadystatechange = this._onStateChange.bind(this, httpRequest, url, options);
    httpRequest.send(options.data || null);//get请求情况下data为null
    return httpRequest;
  },
  jsonp:function(){
    jsonp_str = &#39;jsonp_&#39; + new Date().getTime();
    eval(jsonp_str + &#39; = &#39; + this.options.callback + &#39;;&#39;);    
    this.options.url += &#39;?callback=&#39; + jsonp_str;
    for(var i in this.options.data) {
      this.options.url += &#39;&&#39; + i + &#39;=&#39; + this.options.data[i];
    } 
    var doc_head = document.getElementsByTagName("head")[0],
      doc_js = document.createElement("script"),
      doc_js.src = this.options.url;
    doc_js.onload = doc_js.onreadystatechange = function(){
       if (!this.readyState || this.readyState == "loaded" || this.readyState == "complete"){
         //清除JS
         doc_head.removeChild(doc_js);      
        }
      }   
      doc_head.appendChild(doc_js);
  },
  http:function(){//判断是否支持xmlHttp
    if(window.XMLHttpRequest){
      return new XMLHttpRequest();
    }
    else{
      try{
        return new ActiveXObject(&#39;Msxml2.XMLHTTP&#39;)
      }
      catch(e){
        try {
          return new ActiveXObject(&#39;Microsoft.XMLHTTP&#39;);
        } catch (e) {
          return false;
        }
      }
    }
  },
  _onStateChange:function(http,url,options){
    if(http.readyState==4){
      http.onreadystatechange=function(){};//重置事件为空
      var s=http.status;
      if(typeof(s)==&#39;number&#39;&&s>200&&s<300){
        if(typeof(options.success)!=&#39;function&#39;)return;
        var format=http;
        if(typeof(options.format)==&#39;string&#39;){//判断请求数据格式
          switch(options.format){
            case &#39;text&#39;:
              format=http.responseText;
              break;
            case &#39;json&#39;:
              try{
                format=eval(&#39;(&#39;+http.responseText+&#39;)&#39;);
              }
              catch (e) {
                if (window.console && console.error) console.error(e);
              }
              break;
            case &#39;xml&#39;:
              format=http.responseXML;
              break;
          }
        }
      options.success(format);//成功回调
      }
      else {//请求出问题后处理
        if (window.closed) return;
        if (typeof (options.failure) == &#39;function&#39;) {
          var error = {
            status: http.status,
            statusText: http.statusText
          }
          //  判断是否是网络断线或者根本就请求不到服务器
          if (http.readyState == 4 && (http.status == 0 || http.status == 12030)) {
            //  是
            error.status = -1;
          }
          options.failure(error);
        }
      }
    } 
  }
};

使用方法:

ajax调用举例:

var myAjax=new ZIP_Ajax("http://www.a.com/you.php",{
  method:"get",
  data:"key=123456&name=yuchao",
  format:"json",
  success:function(data){
    ......
  }
})
跨域请求调用举例:
var jsonp=new ZIP_Ajax("http://www.a.com/you.php",{
  method:"jsonp",
  data:{key:"123456",name:"yuchao"},
  callback:function(data){
    ......
  }
})

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

相关文章:

在vue中如何实现微信分享朋友圈,发送朋友

详解如何实现vuex(详细教程)

通过vue.js实现微信支付

以上是自定义ajax支持跨域组件(详细教程)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JavaScript引擎:比较实施JavaScript引擎:比较实施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

使用Next.js(后端集成)构建多租户SaaS应用程序使用Next.js(后端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

如何使用Next.js(前端集成)构建多租户SaaS应用程序如何使用Next.js(前端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript:探索网络语言的多功能性JavaScript:探索网络语言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的演变:当前的趋势和未来前景JavaScript的演变:当前的趋势和未来前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

神秘的JavaScript:它的作用以及为什么重要神秘的JavaScript:它的作用以及为什么重要Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python还是JavaScript更好?Python还是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

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脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

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

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用