この記事では、主に、クロスドメイン コンポーネントのカプセル化をサポートするカスタム 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 メソッドは、var ZIP_Ajax = と同等のコンストラクター リクエストを返します。 function(){ this.request.apply(this, argument); }; オブジェクトの偽装を使用して関数内で構築プロセスを実行します。これは、コンストラクター タスクをリクエスト メソッドに渡すのと同じです。ここでは this.request です。これは ZIP_Ajax のインスタンスのメソッドを指し、this は ZIP_Ajax のインスタンスを指します。最後に、新しいキーワードに従って、これは実際には ZIP_Ajax クラスを指します。クラス ZIP_Ajax を定義すると、次にそのメソッドを定義できます:
XMLHttpRequest 詳細な説明:
XMLHttpRequest はテクノロジーではなく、http プロトコルに完全にアクセスできる主流ブラウザーに組み込まれたオブジェクトです。従来の http リクエストのほとんどは、フォームの送信と http リクエストに基づいて、フォームを返します。 XMLHttpRequest は同期リクエストをサポートしていますが、最大の利点は、新しい ajax リクエストを作成すると、実際には XMLHttpRequest オブジェクトがインスタンス化されることです。主なイベントとメソッドの簡単な紹介:
readystatechange イベント:
XMLHttpRequest が http リクエストを送信すると、readystatechange イベントがトリガーされ、それぞれ 0、1、2 の作成を表す 5 つの値が返されます。 XMLHttpRequest および初期化の完了は、リクエストが送信され、3 は応答が終了していない (つまり、応答ヘッダー データのみを受信した) ことを意味し、4 は完全な応答に対する実際の応答です。
返されたステータスは、サーバーから返されたステータス コードを示します。
一般的に使用されるものは、200 はデータが正常に返されたことを示し、301 永続的なリダイレクト、302 一時的なリダイレクト (安全ではありません) 304 キャッシュされたデータの読み取り 400 リクエストが発生したことを示します 構文エラー、403はサーバーがリクエストを拒否したことを意味します、404はリクエストされたWebページリソースが存在しないことを意味します、405は指定された場所にサーバーが見つからないことを意味します、408はリクエストがタイムアウトしたことを意味します、500サーバー内部エラー、505はサーバーがサポートしていないことを意味します要求された http プロトコルのバージョン。
200-300は成功を示し、300-400はリダイレクトを示し、400-500はリクエストの内容または形式またはリクエスト本文が大きすぎてエラーが発生したことを示し、500+は内部サーバーエラーを示します
openメソッド:
open は 3 つを受け取ります。パラメータは、リクエストのタイプ (get、post、head など)、URL、同期または非同期です。
send メソッド:
リクエストの準備ができたら、send メソッドがトリガーされ、送信されたコンテンツは要求されたデータです (取得リクエストの場合、パラメーターは 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
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. セキュリティ: 1 つのサイト (hi.a.com) が攻撃されると、別のサイト (www.a.com) がセキュリティ ホールを引き起こします。すべての iframe を操作できるようにするには、同じドメインを設定する必要があります
ブラウザはデフォルトでクロスドメイン アクセスを禁止しますが、他のドメイン名からの js は禁止しません。これに基づいて、スクリプト ノード メソッドを作成することで、完全なクロスドメイン通信を実現できます。
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}) }
举例如下:
父页面:
<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){ ...... } })
相关推荐:
JS组件系列--组件封装深入:使用jquery data()和html 5 data-*属性初始化组件_html/css_WEB-ITnose
以上がクロスドメインコンポーネントのカプセル化のためのカスタム Ajax サポートの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。