今回は、カスタム Ajax クロスドメイン コンポーネントのカプセル化について説明します。カスタム Ajax クロスドメイン コンポーネントのカプセル化を使用する際の 注意事項 について、実際のケースを見てみましょう。
Class.create() 分析
プロトタイプを模倣してクラス継承を作成
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 メソッドは constructorリクエストを返します。これは var ZIP_Ajax= function(){ と同等です。 this.request.apply(this, 引数); オブジェクトの偽装を使用して関数内で構築プロセスを実行することは、コンストラクター タスクを request メソッドに渡すことと同じです。ここで、this.request は ZIP_Ajax インスタンスのメソッドであり、this は ZIP_Ajax インスタンスを指します。そして最後に、これは実際には new キーワードに基づいて ZIP_Ajax クラスを指します。クラス ZIP_Ajax を定義すると、次にそのメソッドを定義できます:
XMLHttp詳細な説明をリクエスト:
XMLHttpRequest はテクノロジーではなく、http プロトコルに完全にアクセスできる主流ブラウザーに組み込まれたオブジェクトです。従来の http リクエストのほとんどは、フォームの送信と http リクエストに基づいて、フォームを返します。 XMLHttpRequest は同期リクエストをサポートしていますが、最大の利点は、データを受信するための非同期送信をサポートしていることです。新しい ajax リクエストを作成すると、実際には XMLHttpRequest オブジェクトがインスタンス化されます。主なイベントとメソッドを簡単に紹介します:
readystatechange イベント:
XMLHttpRequest が http リクエストを送信すると、readystatechange イベントがトリガーされ、0、1、2 はそれぞれ XMLHttpRequest の作成、XMLHttpRequest の初期化の完了、およびリクエストの送信を表します。終了していない (つまり、ヘッダー データのみを受信している) 4 は、完全な応答を取得する実際の方法です。
返されたステータスは、サーバーから返されたステータス コードを示します:
一般的に使用されるものには、データが正常に返されたことを示す 200、永続的なリダイレクト (安全ではない) を示す 301、一時的なリダイレクト (安全でない) を示す 304、キャッシュされたデータの読み取りを示す 304、リクエストの構文エラーを示す 400、サーバーがリクエストを拒否したことを示す 403、およびサーバーがリクエストを拒否したことを示す 404 があります。 Web ページをリクエストしています。リソースが存在しません。405 は指定されたロケーション サーバーが見つかりません。408 はリクエストがタイムアウトしたことを意味します。500 サーバー内部エラーです。505 はサーバーがリクエストされた http プロトコル バージョンをサポートしていないことを意味します。 200 ~ 300 は成功を示し、300 ~ 400 はリダイレクトを示し、400 ~ 500 はリクエストの内容または形式またはリクエスト本文が大きすぎてエラーが発生したことを示し、500+ は内部サーバーエラーを示します
オープンメソッド:
open は 3 つのパラメータを受け取ります: リクエスト タイプ
(get、post、head など)、URL、同期または非同期リクエストの準備ができると、send メソッドがトリガーされ、送信されるコンテンツはリクエストされたデータです (get リクエストの場合、パラメーターは null です。
) リクエストが成功すると、成功カスタム メソッドが実行され、そのパラメータは戻りデータになります。ajax クロスドメイン:
クロスドメインとは何ですか?2 つのサイト www.a.com が www.b.com にデータを要求する場合、ドメイン名の不一致によってクロスドメインの問題が発生します。ドメイン名が同じであっても、ポートが異なる場合は、依然としてクロスドメインの問題が発生します (このため、js は静観することしかできません)。クロスドメインかどうかを判断するには、window.location.protocol+window.location.host を使用してクロスドメインかどうかを判断します。たとえば、http://www.baidu.com.
。 js でクロスドメインの問題を解決する方法は何ですか?1.document.domain+iframe
メイン ドメインが同じでサブドメインが異なるリクエストの場合は、ドメイン名 + iframe を解決策として使用できます。具体的なアイデアは、2 つのドメイン名 www.a.com/a.htmlの下に 2 つの異なる ab ファイルがある場合です。 hi.a.com/b.html と同様に、document.domain="a.com" を 2 つの HTML ファイルに追加し、a ファイルに iframe を作成して iframe の contentDocument を制御できます。 2 つのファイルについて会話することができます。例は次のとおりです:
www.a.com の .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文件中元素 }
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中文网其它相关文章!
推荐阅读:
以上がカスタム Ajax クロスドメイン コンポーネントのパッケージ化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。