2012-04-09 12 views
20

別のサーバー/ドメインからXMLを解析する際に、クロスドメインの問題を回避するにはどうすればよいですか?誰か私に例を教えてもらえますか?この例は、JavaScriptだけでも十分であるため、jQueryに限定する必要はありません。jQueryでXMLクロスドメインを解析する方法は?

+0

crossdomainとはどういう意味ですか? –

+1

JavaScriptからのクロスドメイン実行のみがJSONPです。 – AlienWebguy

+0

"スクリプトとJSONPリクエストは、同じ発信元ポリシーの制限の対象ではありません。" –

答えて

66

クロスドメインXMLが機能しない理由を完全に理解するには、クロスドメインJSONがどのように容易化されるかを最初に見ておくことをお勧めします。上記の例では

$.ajax({ 
    url: '/user.php?userId=123', 
    success: function(data) { 
     alert(data); // alerts the response 
    }); 

、AJAX要求は、ドメインに対する構成されています

まず、あなたはjQueryのでAJAXリクエストを作るときに何が起こるか見てみましょう。パスの前に別のドメインを追加しようとすると、要求はセキュリティ例外と共に失敗することがわかります。

ただし、ブラウザが別のドメインにリクエストできないとは限りません。ここではあなたに慣れていることでしょう例です。ページ上でJavaScriptをインポートする方法の知識に基づいて

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 

、我々は別のドメインに存在するリソースをロードすることが可能であることを参照してください!

JSONPは、この知識を利用するコンセプトです。 JSONPは「JSON With padding」の略で、JavaScriptオブジェクトを文字列表記で表現できるという事実と、JavaScriptスクリプトタグが外部ドメインからコンテンツを読み込んで実行できるという事実にも成功しています。ボンネットの下に

、それは正確ではないかもしれないが、jQueryのJSONPは、次のようになります。

// programmatically load a script tag on the page using the given url 
function loadRemoteData(url) { 
    var script = document.createElement("script"); 
    script.setAttribute("type","text/javascript"); 
    script.setAttribute("src", url); 
    document.getElementsByTagName("head")[0].appendChild(script); 
} 

はまた、どこかのページに、私たちは、コールバックハンドラを定義します。ここでは

function processData(jsonResult) { 
    alert(JSON.stringify(jsonResult)); //alert the JSON as a string 
} 

// make a request for the data using the script tag remoting approach. 
loadRemoteData("http://example.com/users.php?userId=123&callback=processData"); 

これを正しく行うには、PHPスクリプトが必要です。どちらもJSON形式のデータを返します。また、パラメータとして渡すJavaScript関数名の形式で文字列の周りに「パディング」を追加する必要があります。我々はJavaScriptコンテンツのように実行される知っているので

processData({ "userId" : "123" , "name" : "James" , "email" : "[email protected]" }); 

:私たちは、FirebugのやChrome NET]タブでそれを見ていた場合、

このように、サーバーからの応答があります)、このような何かを「コールバック」ダウンロードされるとすぐに、先ほど定義したprocessData関数がすぐに呼び出され、JSON文字列がパラメータとして渡されます。 JSON.stringifyを使用してオブジェクトを文字列に変換し直して警告します。

それはオブジェクトなので、私もそれはそうのような性質、のアクセスができます

function processData(jsonResult) { 
    alert(JSON.stringify(jsonResult)); //alert the JSON as a string 

    // alert the name and email 
    alert("User name is " + jsonResult.name + " and email is " + jsonResult.email); 
} 

最後に、メインの質問に移りましょう:は、JSONPはXMLを取得するために使用することができ、あるいは我々は、XMLのクロスを解析することができます-ドメイン?他の人が指摘しているよう答えは、NO響きですが、のは、例を使って、理由を見てみましょう:生のXMLは、関数に渡された場合に何が起こるか

processData(<?xml version="1.0"><user><userid>12345</userid><name>James</name><email>[email protected]</email></user>); 

、? JavaScriptはXMLをJSONに変換する方法がないため、壊れてしまいます。

しかし、私たちは引用符でXMLを入れたとします

processData("<?xml version="1.0"><user><userid>12345</userid><name>James</name><email>[email protected]</email></user>"); 

は今、この例では、化するJsonResult変数は、実際に私たちがして働くことができる文字列を取ります。いくつかのJavaScriptのXML解析ユーティリティを使用して、その文字列をXML DOM Parserにロードして、それを処理することができます。

しかし、これは純粋なXMLではなく、フードのJavaScriptレスポンスです。 PHPサーバーの応答タイプはtext/javascriptのままですが、スクリプトタグを使用して実際には単純なJavaScriptをロードしています。

要約すると、「XMLP」またはXMLを埋め込みで使用することができます(私はこれを作成しました。実際はそうではありませんでした)。しかし、実際にレスポンスを変更するすべての問題関数コールバックラッパーを返すだけで、出力をJSONに変換し、ブラウザが自動的かつネイティブに変換を処理し、XMLパーサを使用する手間を省くことができます。

何らかの理由でデータをXML形式で保存した方が簡単な場合は、レスポンスを変更してJavaScriptラッパーを付けることができます。

レガシーアプリケーションからのXMLデータがデータベースに保存されていて、スクリプトタグのリモート処理またはJSONP呼び出しを使用してクライアントサイドに戻すと、この情報が役立つことがあります。

+8

これはとても便利です。+1。あなたは名誉に値する – defau1t

4

クロスドメインのajaxリクエストからXMLを取得するための非常に優れたソリューションが見つかりました。

jQuery 1.5以降、dataType "jsonp xml"(http://api.jquery.com/jQuery.ajax/)を使用することができます。

は、だから私は、これを使用:

private static Stream GetXmlPStream(string result, string callback) 
     { 
      if (result == null) 
       result = string.Empty; 

      result = EncodeJsString(result); 

      if (!String.IsNullOrEmpty(callback)) 
       result = callback + "(" + result + ");"; 

      byte[] resultBytes = Encoding.UTF8.GetBytes(result); 

      if (WebOperationContext.Current != null) 
       WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml"; 
      return new MemoryStream(resultBytes); 
     } 

と魔法の方法(私が見つけた:私はjQueryのによって作成されたコールバック内のXML文字列の結果をカプセル化するために使用私のウェブサービスのための

$.ajax({ 
      type: "GET", 
      url: "http://yoururl", 
      dataType: "jsonp xml", 
      success: function(xmlResponse) { // process data } 
     }); 

サーバー側のそれはあなたのXML文字列(JavaScriptはそれを解析することができます)を衛生的にする必要がありますので、別のスタックスレッドで):

private static string EncodeJsString(string s) 
     { 
      StringBuilder sb = new StringBuilder(); 
      sb.Append("\""); 
      foreach (char c in s) 
      { 
       switch (c) 
       { 
        case '\"': 
         sb.Append("\\\""); 
         break; 
        case '\\': 
         sb.Append("\\\\"); 
         break; 
        case '\b': 
         sb.Append("\\b"); 
         break; 
        case '\f': 
         sb.Append("\\f"); 
         break; 
        case '\n': 
         sb.Append("\\n"); 
         break; 
        case '\r': 
         sb.Append("\\r"); 
         break; 
        case '\t': 
         sb.Append("\\t"); 
         break; 
        default: 
         int i = (int)c; 
         if (i < 32 || i > 127) 
         { 
          sb.AppendFormat("\\u{0:X04}", i); 
         } 
         else 
         { 
          sb.Append(c); 
         } 
         break; 
       } 
      } 
      sb.Append("\""); 

      return sb.ToString(); 
     } 

これが助けてくれることを願っています!

+9

私はこれを試したときに 'Uncaught SyntaxError:Unexpected token <'エラーを受け取りました。例えば '$ .get( 'http://www.webservicex.net/geoipservice.asmx/GetGeoIPContext'、function(data) {console.log(data);}、 'jsonp xml'); ' – 10basetom

+2

これは、サーバーコードにアクセスできる場合にのみ有効です。 –

関連する問題