ホームページ  >  記事  >  ウェブフロントエンド  >  カスタム Ajax はクロスドメイン コンポーネントをサポートします (詳細なチュートリアル)

カスタム Ajax はクロスドメイン コンポーネントをサポートします (詳細なチュートリアル)

亚连
亚连オリジナル
2018-06-06 17:28:491778ブラウズ

この記事では、クロスドメイン コンポーネントのカプセル化のカスタム 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 はサーバーがリクエストされた Web リソースをサポートしていないことを意味します。 httpプロトコルのバージョン。

200〜300は成功を示し、300〜400はリダイレクトを示し、400〜500はリクエストの内容または形式またはリクエスト本文が大きすぎてエラーが発生したことを示し、500+は内部サーバーエラーを示します

openメソッド:

open は 3 つを受け取ります。パラメータは、リクエスト タイプ (get、post、head など)、URL、同期または非同期です。

send メソッド:

リクエストの準備ができたら、send メソッドがトリガーされ、送信されたコンテンツはリクエストされたデータです (取得リクエストの場合、パラメーターは null です。

リクエストが成功した後、成功カスタム メソッドが実行され、そのパラメーターは戻りデータです。

ajax クロス-ドメイン:

クロスドメインとは何ですか?

2 つのサイト www.a.com がデータを送信する場合、ドメイン名が一致しない場合でも、クロスドメインの問題が発生します。名前は同じですが、ポートが異なるとクロスドメインの問題が発生します (このため、js は待機してクロスドメインかどうかを判断することしかできません)。単に window.location.protocol+window.location で判断します。ホスト (例: http://www.baidu.com)。

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

1. document.domain+iframe

同じメイン ドメインのリクエストの場合具体的なアイデアとしては、2 つの異なる ab ファイル www.a.com/a.html

が 2 つのドメイン名 /b の下にある場合です。 .html の場合、2 つの HTML ファイルに document.domain="a.com" を追加し、iframe の contentDocument を制御する 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文件中元素
  }

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

document.domain="a.com";

質問:

1 、セキュリティ、1 つのサイト (hi.a.com) が攻撃されると、別のサイト (www.a.com) がセキュリティ ホールを引き起こします。 2. ページ内に複数の iframe が導入されている場合、すべての iframe が動作できる必要があります。同じドメインを設定する必要があります

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

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

a. リクエスト イニシエーター ページにスクリプトを動的にロードします。スクリプトはレシーバーを指します。このアドレスによって返される 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){
    ......
  }
})

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

相关文章:

在vue中如何实现微信分享朋友圈,发送朋友

详解如何实现vuex(详细教程)

通过vue.js实现微信支付

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

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。