ホームページ > ウェブフロントエンド > jsチュートリアル > クロスドメインコンポーネントのカプセル化のためのカスタム Ajax サポートの詳細な説明

クロスドメインコンポーネントのカプセル化のためのカスタム Ajax サポートの詳細な説明

小云云
リリース: 2018-02-09 09:49:28
オリジナル
1043 人が閲覧しました

この記事では、主に、クロスドメイン コンポーネントのカプセル化をサポートするカスタム 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

と hi がある場合です。 com/b.html の場合、2 つの HTML ファイルに document.domain="a.com" を追加し、そのファイル内に iframe を作成して iframe の contentDocument を制御し、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文件中元素
  }
ログイン後にコピー

hi.a.com の b.html ファイル内

document.domain="a.com";


問題:


1. セキュリティ: 1 つのサイト (hi.a.com) が攻撃されると、別のサイト (www.a.com) がセキュリティ ホールを引き起こします。すべての iframe を操作できるようにするには、同じドメインを設定する必要があります

2. スクリプトを動的に作成します (伝説的な jsonp メソッド)


ブラウザはデフォルトでクロスドメイン アクセスを禁止しますが、他のドメイン名からの js は禁止しません。これに基づいて、スクリプト ノード メソッドを作成することで、完全なクロスドメイン通信を実現できます。

a.スクリプトの URL は、受信側のバックエンドを指します。このアドレスによって返される JavaScript メソッドは、イニシエーターによって実行されます。この URL は、送信パラメーターの取得のみをサポートします。


b. スクリプトをロードするときに、コールバック処理用のクロスドメイン 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})
}
ログイン後にコピー

レシーバー:

レシーバーは、リクエスト内のコールバックでありパラメーターを割り当てる実行関数を返すだけで済みます。


3. html5 を使用した PostMessage:


HTML5 の新機能の 1 つは、現在、ほとんどのブラウザー (IE8+ を含む) でサポートされ、使用されています。クロスドメインの問題は存在しません。 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){
    ......
  }
})
ログイン後にコピー

相关推荐:

JS组件系列--组件封装深入:使用jquery data()和html 5 data-*属性初始化组件_html/css_WEB-ITnose

Ajax跨域的完美解决方案实例分享

最全ajax跨域解决方案

以上がクロスドメインコンポーネントのカプセル化のためのカスタム Ajax サポートの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート