Home >Web Front-end >JS Tutorial >Custom ajax cross-domain component packaging
This time I will bring you custom ajax cross-domain component encapsulation. What are the precautions when using custom ajax cross-domain component encapsulation? Here are actual cases, let’s take a look.
Class.create() analysis
Create class inheritance by imitating 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 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); }; Using object impersonation to perform a construction process inside the function is equivalent to handing over the constructor task to the request method. Here this.request is the method of the ZIP_Ajax instance, and this points to the ZIP_Ajax instance, after apply This points to ZIP_Ajax, and finally this actually points to the ZIP_Ajax class based on the new keyword. With the definition of class ZIP_Ajax, you can then define its methods:
XMLHttpRequest detailed explanation:
XMLHttpRequest is not a technology but an object built into mainstream browsers that can fully access 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 initialization of XMLHttpRequest, and sending of the request. 3 represents that the response has not ended (that is, only the response has been received). Header data) 4 is the real way to get a complete response.
The returned status indicates the status code returned by the server:
Commonly used ones include 200 indicating successful return of data, 301 permanent redirection, 302 indicating temporary redirection (unsafe), 304 reading cached data , 400 indicating a syntax error in the request, and 403 indicating The server rejects the request. 404 indicates that the requested web resource does not exist, 405 cannot find the server at the specified location, 408 indicates that the request has timed out, 500 internal server error, and 505 indicates that 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, and 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 parameter is the return data;
ajax cross-domain:
What is cross-domain?
If two sites www.a.com want to request data from www.b.com, there will be a cross-domain problem caused by inconsistent domain names. Even if the domain name is the same, if the ports are different, there will be cross-domain problems (for this reason, js can only sit back and watch). To determine whether it is cross-domain, just use window.location.protocol window.location.host to determine whether it is cross-domain. For example, http://www.baidu.com.
What are several ways to solve cross-domain problems with js?
1、document.domain iframe
For requests with the same main domain but different subdomains, domain name iframe can be used as a solution. The specific idea is that if there are two different ab files under two domain names www.a.com/a.html
As well as hi.a.com/b.html, we can add document.domain="a.com" to the two html files, and then create an iframe in the a file to control the contentDocument of the iframe, so that the two files You can have a conversation. Examples are as follows:
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文件中元素 }
in the a.html file on www.a.com
in the b.html file on hi.a.com document.domain="a.com";
question:
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 += '?callback=' + 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: 'get', async: true},options||{}); if(options.method=="get"){ url+=(url.indexOf('?')==-1?'?':'&')+options.data; options.data=null; } httpRequest.open(options.method,url,options.async); if (options.method == 'post') { httpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8'); } httpRequest.onreadystatechange = this._onStateChange.bind(this, httpRequest, url, options); httpRequest.send(options.data || null);//get请求情况下data为null return httpRequest; }, jsonp:function(){ jsonp_str = 'jsonp_' + new Date().getTime(); eval(jsonp_str + ' = ' + this.options.callback + ';'); this.options.url += '?callback=' + jsonp_str; for(var i in this.options.data) { this.options.url += '&' + i + '=' + 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('Msxml2.XMLHTTP') } catch(e){ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) { return false; } } } }, _onStateChange:function(http,url,options){ if(http.readyState==4){ http.onreadystatechange=function(){};//重置事件为空 var s=http.status; if(typeof(s)=='number'&&s>200&&s<300){ if(typeof(options.success)!='function')return; var format=http; if(typeof(options.format)=='string'){//判断请求数据格式 switch(options.format){ case 'text': format=http.responseText; break; case 'json': try{ format=eval('('+http.responseText+')'); } catch (e) { if (window.console && console.error) console.error(e); } break; case 'xml': format=http.responseXML; break; } } options.success(format);//成功回调 } else {//请求出问题后处理 if (window.closed) return; if (typeof (options.failure) == 'function') { 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){ ...... } })
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
The above is the detailed content of Custom ajax cross-domain component packaging. For more information, please follow other related articles on the PHP Chinese website!