Home >Web Front-end >JS Tutorial >Custom ajax supports cross-domain components (detailed tutorial)

Custom ajax supports cross-domain components (detailed tutorial)

亚连
亚连Original
2018-06-06 17:28:491810browse

This article gives you a detailed analysis of the knowledge points related to custom ajax support for cross-domain component encapsulation. Friends who are interested in this can refer to it.

Class.create() analysis

Imitate prototype to create class inheritance

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 definition: ZIP_Ajax=Class.create ();

The create method returns a constructor request, which is equivalent to var ZIP_Ajax= function(){ this.request.apply(this, arguments); }; Use object impersonation in the function A construction process is executed internally, which is equivalent to handing over the constructor task to the request method. This.request here is the method of the ZIP_Ajax instance, and this points to the ZIP_Ajax instance. This after apply points to ZIP_Ajax. Finally, according to the new keyword, this actually points to the ZIP_Ajax class. With the definition of the class ZIP_Ajax, you can then define its method:

XMLHttpRequest Detailed explanation:

XMLHttpRequest is not a technology but a built-in feature of mainstream browsers An object with full access to the http protocol. Most of the traditional http requests are based on form submission and request http, and then return a form. While XMLHttpRequest supports synchronous requests, the biggest advantage is that it supports asynchronous transmission and reception of data. Creating a new ajax request is actually instantiating an XMLHttpRequest object. Briefly introduce the main events and methods:

readystatechange event:

When XMLHttpRequest sends an http request, a readystatechange event will be triggered. The event returns five values. 0, 1, and 2 respectively represent the creation of XMLHttpRequest, completion of XMLHttpRequest initialization, and sending the request. 3 represents that the response has not ended (that is, only the response header data is received). 4 is the real response to the complete response.

The returned status indicates the status code returned by the server:

Commonly used ones are 200 indicating successful return of data, 301 permanent redirection, 302 temporary redirection (unsafe), and 304 read. Cache data 400 means there is a syntax error in the request, 403 means the server rejects the request, 404 means the requested web resource does not exist, 405 cannot find the server at the specified location, 408 means the request has timed out, 500 server internal error, 505 means the server does not support the requested http protocol. Version.

200-300 indicates success, 300-400 indicates redirection, 400-500 indicates that the request content or format or the request body is too large, causing an error, 500 indicates an internal server error

open Method:

open receives three parameters: request type (get, post, head, etc.), url, synchronous or asynchronous

send method:

When the request is ready, the send method will be triggered, and the content sent is the requested data (if it is a get request, the parameter is null;

After the request is successful, the success custom method will be executed, and its parameters are Return data;

ajax cross-domain:

What is cross-domain?

If two sites www.a.com want to go to www.b When .com requests data, there are cross-domain problems caused by inconsistent domain names. Even if the domain names are the same, if the ports are different, there will be cross-domain problems (for this reason, js can only stand by and watch). Determining whether it is cross-domain is just through window.location.protocol window.location.host to determine, for example, http://www.baidu.com.

What are several ways js can solve cross-domain problems?

1.document .domain iframe

For requests with the same main domain but different subdomains, you can use domain name iframe as a solution. The specific idea is that if there are two different ab files under two domain names www.a.com/a .html

and hi.a.com/b.html, we can add document.domain="a.com" to the two html files, and then control it by creating an iframe in the a file iframe's contentDocument, so that the two files can communicate. For example: the a.html file on

www.a.com and the b on

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.

document.domain="a.com";

Problem in the html file:

1. Security, when a site (hi.a.com) is attacked Later, another site (www.a.com) will cause a security vulnerability. 2. If multiple iframes are introduced into a page, in order to be able to operate all iframes, the same domain must be set.

2. Dynamically create script (the legendary jsonp method)

The browser prohibits cross-domain access by default, but does not prohibit js files from other domain names in the page, and can execute the imported js files Methods, etc. Based on this, we can achieve complete cross-domain communication by creating script node methods. The implementation steps are:

a. Dynamically load a script on the request initiator page. The url of the script points to the receiver's backend. The javascript method returned by the address will be executed by the initiator. The url can pass parameters and only supports get submission parameters.

b. When loading the script, call the cross-domain js method for callback processing (jsonp).

For example:

Initiator

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})
}

Receiver:

The receiver only needs to return an execution function, which is the callback in the request and assign parameters.

3. Use 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实现微信支付

The above is the detailed content of Custom ajax supports cross-domain components (detailed tutorial). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn