クロスドメインXMLHttpRequest

AJAXテクノロジーの重要なコンポーネントはXMLHttpRequestです。 このオブジェクトを使用すると、ページをリロードすることなくサーバーにHTTPリクエストを送信できます。



通常、XMLHttpRequestの操作は次のとおりです。

1. XMLHttpRequestオブジェクトのインスタンスを作成する

2.オブジェクトの状態が変化したときに発生するイベントハンドラーのインストール(onreadystatechange)

3.接続を開く(開く)および要求を送信する(送信)



残念ながら、XMLHttpRequestは、XMLHttpRequestを使用するページと同じドメインにあるファイルでのみ機能します。 つまり、要求は、現在のページと同じドメイン、プロトコル、およびポートを持つアドレスに対してのみ行うことができます。 これはセキュリティ上の理由で行われ、別のサイトからデータ/コンテンツを取得する必要がある場合に問題を引き起こします。



最近、この問題が目の前に現れ、非常に簡単な解決策が選択されました。これについては後で説明します。



プロキシ! クロスドメインクエリのためのシンプルで直感的な方法。 メソッドの本質は次のとおりです。



1. XMLHttpRequestは、ドメインのPHPスクリプトにアクセスし、リクエストメソッド、アドレス、およびパラメーターを渡します

2. PHPスクリプトは、プロキシとして機能します。 つまり、渡されたパラメーターに基づいて要求を作成し、別のサーバーの応答をJSスクリプトに返します



クロスドメインリクエストのプロキシであるPHPスクリプトの動作は、CURLに基​​づいています。



proxy.phpスクリプト自体は次のとおりです。

<?php

header("Content-Type: text/xml; charset=windows-1251");

//

$method = (empty($_GET['method'])) ? 1 : $_GET['method'];

$url = $_GET['url'];

$url = (empty($_GET['url'])) ? die("no url") : $_GET['url'];

$params = $_GET['params'];

//

$allowed = array(1 => "~http:\/\/(www\.)?habrahabr\.ru\/~", 2 => "~http:\/\/(www\.)?el\-egoisto\.com\/~");

$count = count($allowed);

for ($i = 1; $i <= $count; $i++)

{

if (preg_match($allowed[$i],$url))

{

// -

$ch = curl_init();

switch ($method)

{

case 1:

// GET

curl_setopt($ch, CURLOPT_URL, $url."?".$params);

break;

case 2:

// POST

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $params);

break;

}

curl_setopt($ch, CURLOPT_HEADER, 0);

$response = curl_exec($ch);

$header_size = curl_getinfo($ch,CURLINFO_HEADER_SIZE);

$xml = substr($response,$header_size);

echo $xml;

curl_close($ch);

exit();

}

}

?>







XMLHttpRequestはそれにアクセスし、3つのパラメーターを渡します。

1.メソッド-GETリクエストの場合は1、POSTの場合は2

2. url-リクエストアドレス

3. params-要求パラメーター



PHPスクリプトは、入力パラメーターを確認し、url(regexp $の配列)への要求の送信が許可されているかどうかを確認し、実際に要求を送信し、リモートサーバーから応答を返します。



JSから、このPHPスクリプトは次のように使用されます。



XMLHttpRequestを操作するための2つの関数、CreateReqとGetDataがあります。 最初のものはオブジェクトのインスタンスを作成し、2番目のものはハンドラーをセットアップしてリクエストを送信します。

function CreateReq()

{

var req = null;

if (window.XMLHttpRequest)

{

try

{

req = new XMLHttpRequest();

}

catch(e)

{

req = null;

}

}

else if (window.ActiveXObject)

{

try

{

req = new ActiveXObject("Msxml2.XMLHTTP");

}

catch(e)

{

try

{

req = new ActiveXObject("Microsoft.XMLHTTP");

}

catch(e)

{

req = null;

}

}

}

return req;

}



function GetData(url,callback)

{

req = new CreateReq;



if(req != null)

{

req.onreadystatechange = callback;

req.open('GET', url, true);

req.send(null);

}

else alert(" ..");

}









Habrからカルマと強度を受け取る例を使用して、GETリクエストを送信することを考えてみましょう:)



function GetHabraMe()

{

GetData("/proxy.php?method=1&url="+encodeURIComponent("http://habrahabr.ru/api/profile/lordeg"),GetHabraCallback);

}



function GetHabraCallback()

{

if(req.readyState == 4)

{

if(req.status == 200)

{

var xmlDoc = req.responseXML;

var karma = xmlDoc.getElementsByTagName("karma").item(0).firstChild.data;

var rating = xmlDoc.getElementsByTagName("rating").item(0).firstChild.data;

var place = document.getElementById("data");

if(place != null)

{

place.innerHTML = ": "+karma+"<br>: "+rating+";

}

}

}

return false;

}









GetHabraMeは、 proxy.phpを使用してGETリクエストをhabrahabr.ru/api/profile/lordegに送信し、結果はID「data」の要素に「返されます」。



POSTリクエストの送信はほぼ同じです。



function GetPings()

{

var d_topic = document.getElementById("topic");

if (d_topic.innerHTML == " ")

{

GetData("/proxy.php?method=2&url="+encodeURIComponent("http://el-egoisto.com/frontend.php")+"¶ms="+encodeURIComponent("func=recent&owner=9&id=1&cutoff=48"),GetMyLastPingsCallback);

}

}







「戦闘条件」での実装はここで見ることができます-lord-phoenix.com (リンク「現在の音楽」と「habralordeg」):)

私は独創的であるふりをするのではなく、自分の目の前で生じた問題の解決策をブログのトピックの形で作成することにしました。 誰かが私の経験から恩恵を受けるかもしれません。



関連資料:

1.xmlhttprequest.ru

2. ru.wikipedia.org/wiki/XMLHttpRequest

3. ru.wikipedia.org/wiki/AJAX

4. ru.wikipedia.org/wiki/CURL



All Articles