詳細な回答: カスタム Ajax はクロスドメイン コンポーネントのカプセル化をサポートします

亚连
リリース: 2018-05-22 09:27:30
オリジナル
1135 人が閲覧しました

この記事では、クロスドメイン コンポーネントのカプセル化のカスタム 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); }; オブジェクトの偽装を使用して、関数内で構築プロセスを実行します。これは、コンストラクター タスクをリクエスト メソッドに渡すのと同じです。これは 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 がデータを送信する場合、ドメイン名が一致しない場合でも、クロスドメインの問題が発生します。名前が同じでも、ポートが異なると、クロスドメインの問題が発生します (このため、js はクロスドメインかどうかを待機して判断することしかできません)。 .host (例: http://www.baidu.com)。

js のクロスドメイン問題の解決策は何ですか?

1. document.domain+iframe

同じメイン ドメインのリクエストの場合ただし、サブドメインが異なる場合は、解決策としてドメイン名 + iframe を使用できます。具体的なアイデアは、2 つのドメイン名 / の下に 2 つの異なる ab ファイルがある場合です。 b.html の場合、2 つの HTML ファイルに document.domain="a.com" を追加し、a ファイルに 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、セキュリティ、あるサイト(hi.a.com)が攻撃されると、別のサイト(www.a.com)がセキュリティホールを引き起こす 2. ページ内に複数の iframe が導入されている場合、すべての 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新功能有一个就是跨文档消息传输,如今大部分浏览器都已经支持并使用(包括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){
    ......
  }
})
ログイン後にコピー

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

MUi框架ajax请求WebService接口实例_AJAX相关

Struts2和Ajax数据交互(图文教程)

原生ajax写的上拉加载实例(图文教程)

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

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