メインコンテンツへ移動

JS 学習ノート 10_Ajax

無料2015-04-13#JS#Ajax

この記事では Ajax 技術、XHR オブジェクトの使用方法と注意点、同源ポリシー、クロスドメイン方法、クロスサイトリクエストフォージェリなどについて紹介します

##1.Ajax の概要

Asynchronous JavaScript + XML、JavaScript とサーバー間の通信をサポートします。ページを unload することなくサーバーから新しいデータを取得し、より良いユーザーエクスペリエンスを実現します(従来のクリック - 待機インタラクションとは異なるエクスペリエンス)。

IE5 が最初にサポートを提供し、MSXML ライブラリに XHR オブジェクト(XMLHttpRequest)を追加しました。new ActiveXObject(str) によって XHR オブジェクトを作成できます。便利ではありませんでしたが、少なくともネイティブサポートでした

##2.XHR オブジェクト

XMLHttpRequest、[IE6-] は XHR オブジェクトの実装が他のブラウザと異なりますが、オブジェクト検出によってクロスブラウザの XHR オブジェクトを作成できます。具体的なコードは以下の通りです:

/*获取 HttpRequest 对象,可以兼容各个浏览器 包括 IE5.5+*/
function getHttpObject(){
????if(typeof XMLHttpRequest == "undefined"){//如果该对象未定义,则自定义该对象
????????XMLHttpRequest = function(){
????????????try{
????????????????return new ActiveXObject("Msxml2.XMLHTTP.6.0");
????????????}catch(e){}
????????????try{
????????????????return new ActiveXObject("Msxml2.XMLHTTP.3.0");
????????????}catch(e){}
????????????try{
????????????????return new ActiveXObject("Msxml2.XMLHTTP");
????????????}catch(e){}
????????????try{//老版本的 Internet Explorer(IE5 和 IE6)
????????????????return new ActiveXObject("Microsoft.XMLHTTP");
????????????}catch(e){}
?????????????
????????????return false;
????????}
????}
?????
????return new XMLHttpRequest();
}

XHR オブジェクトのプロパティは以下の通りです:

  • responseText:レスポンスボディ

  • responseXML:レスポンスコンテンツが"text/xml"または"application/xml"の場合、このプロパティはレスポンスデータの XML DOM ドキュメントを保持します

  • status:HTTP レスポンスステータス(404、200 など)

  • statusText:HTTP ステータス説明、信頼できません。ブラウザによって異なるため、status ステータスコードを使用するのが最も信頼できます

  • readyState:主に非同期リクエストに使用されます。同期リクエストでも使用できますが意味はありません。readyState の 5 つの値は以下の通りです:

    • 0:未初期化。open メソッドがまだ呼び出されていません

    • 1:開始。open は呼び出されたが send は呼び出されていません

    • 2:送信。send は呼び出されたがレスポンスを受け取っていません

    • 3:受信。レスポンスデータの一部を受け取りました

    • 4:完了。すべてのデータを受け取り、データが利用可能になりました

##3.XHR オブジェクトを使用してコールバック関数を実行

var xhr = getHttpObject();
xhr.onreadystatechange = function(){
??if(xhr.readyState === 4){
????if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){//本来只用检测 200 成功和 304 不变但有些浏览器会把 200 错报成 204
??????//执行 callback
????}
????else{
??????//请求失败
????}
??}
}

注意:readyystatechange イベントハンドラを open 関数のに設定する必要があります。すべてのブラウザとの互換性を確保するためです

##4.XHR オブジェクトを使用して get/post リクエストを実行

//get 请求
xhr.open('get', url, false/true);//初始化,false/true ~ 同步/异步
xhr.send(null);//发送请求,null 是为了兼容性
//post 请求
xhr.open('post', url, false/true);//同上
xhr.send(str);
/* 可以在 open 后 send 前设置请求头,比如添加 cookie 信息
xhr.setRequestHeader(strHeader, strValue);
*/

注意:サーバーは post リクエストと Web フォーム送信リクエストの処理方法が異なりますが、HTTP ヘッダーを変更してフォーム送信をシミュレートできます

ただし、フォームデータを送信する場合、send のパラメータ str はシリアライズされたフォームデータである必要があります。この場合、シリアライズ関数を手動で実装する必要があり、面倒です。JQuery はシリアライズサポートを提供しており、$('#mForm').serialize() でフォームを直接シリアライズできます

##5.リクエストの中止

xhr.abort(); レスポンスが返される前にリクエストを中止できます。abort 後、イベントはトリガーされず、xhr のレスポンス関連プロパティへのアクセスもできません

注意:リクエストを中止した後、XHR オブジェクトの参照を解除する必要があります。XHR オブジェクトの再利用は推奨されません(メモリのため)

##6.post を使うべきか get を使うべきか?

post リクエストはより多くのリソースを消費し、データ転送速度も get リクエストよりもはるかに遅いです

しかし get リクエストは安全ではなく、IE には URI 長の制限があります(2048 バイトを超えない)。そのためできるだけ get を使用し、ダメな場合は post を使用します

##7.CORS の概要

Cross-Origin Resource Sharing、クロスオリジンリソース共有、Ajax は同源ポリシーの制限を受けます。一部の CORS 技術を通じて同源ポリシーの制限を打破できます。例えば IE8 の XDR オブジェクト

他のブラウザは XHR オブジェクトを拡張することで CORS のネイティブサポートを実装しました:open 関数の url パラメータを絶対 URL に設定するだけです

そのため曖昧さを排除するため、ローカルリソースにアクセスするときは相対 URL を使用し、リモートリソースにアクセスするときは絶対 URL を使用する必要があります

##8.その他のクロスドメイン技術

  1. 画像 Ping

    var img = new Image();
    img.onload = img.onerror = function(){
      //响应返回,执行回调函数
    }
    img.src = url;//一旦设置了 src 属性,就会立即请求(加载)图片,而不是把 img 元素插入 DOM 树后才开始
    

get リクエストのみ送信でき、サーバーのレスポンステキストにアクセスできません。主にユーザーのページクリック追跡や動的広告のインプレッション数に使用されます

  1. JSONP

JSON with Padding、ブラウザとサーバー間の双方向通信をサポートし、レスポンステキストに直接アクセスできます。しかし、リクエストの失敗を判断しにくく、他のドメインからコードを読み込んで実行するため、セキュリティ上の問題があります

クロスドメイン技術を紹介する素晴らしいブログ記事があります

##9.CSRF 攻撃

Cross-Site Request Forgery、クロスサイトリクエストフォージェリ、ページに直接 Ajax コードを挿入し、同源ポリシーの制限はなく、リクエストを偽造して機密データにアクセスします。

防止方法には以下があります:

  1. リソースへのアクセスに SSL 接続を要求する

  2. 各リクエストに特殊アルゴリズムで計算された認証コードを添付することを要求する

コメント

コメントはまだありません

コメントを書く