最近、web サービスにアクセスするときに ajax でクロスドメインの問題が発生したため、オンラインで情報を検索し、次のようにまとめました (多くは、他の人の良いと思われる要約をコピーしたものです)
> を実行します
実装したコードから始めましょう:
フロントエンド コード:
$.ajax({ type: "get", url: "http://localhost/service1.asmx/getelevatorstatusjsondata?jsoncallback=?", datatype: "jsonp", jsonp: "json", data: "", success: function (result) { var data = eval(result); for (var i = 0; i < data.length; i++) { alert(data[i].id + "--" + data[i].name); } }, error: function (a, b, c) { alert(c); } });
サーバー コード:
/// <summary> /// 获取状态数据信息 /// </summary> /// <returns></returns> [webmethod] public void getelevatorstatusjsondata() { list<list<deviceinfo>> elevatordatas = new list<list<deviceinfo>>(); list<senddicdate> searchlist = xmlserializehelper.xmldeserializefromfile<list<senddicdate>>(@configutil.servicepath + configutil.getconfigbykey("xmlpath") + "查询指令信息.xml", encoding.utf8); foreach (senddicdate item in searchlist) { string key = item.portno + "-" + item.bordrate + "-" + item.sendtype; list<deviceinfo> deviceinfolist = (list<deviceinfo>)context.cache.get(key); elevatordatas.add(deviceinfolist); } string result = ""; datacontractjsonserializer json = new datacontractjsonserializer(elevatordatas.gettype()); using (memorystream stream = new memorystream()) { json.writeobject(stream, elevatordatas); result = encoding.utf8.getstring(stream.toarray()); } string jsoncallback = httpcontext.current.request["jsoncallback"]; result = jsoncallback + '(' + result + ')'; httpcontext.current.response.write(result); httpcontext.current.response.end(); }
c#
上記は c# サーバーを呼び出すための実装コードです。以下は java 側です。パラメータは異なる場合がありますが、原理は同じです。
java:
string callbackfunname = context.request["callbackparam"]; context.response.write(callbackfunname + "([ { \"name\":\"john\"}])");
追記: クライアントの jsonp パラメータは、url を通じてパラメータを渡すために使用され、jsonpcallback パラメータのパラメータ名が渡されます。少し混乱しますが、平たく言うと次のようになります。
jsonp: ""
jsonpcallback:""
ちなみに: chrome ブラウザでは、クロスの目的を達成するために、サーバー側でヘッダー情報 context.response.addheader("access-control-allow-origin", "*"); を設定することもできます。 -domain リクエスト。また、次の ajax パラメータを設定する必要はありません。
datatype : "jsonp", jsonp: "callbackparam", jsonpcallback:"jsonpcallback1"
データは通常の ajax リクエストを通じて取得できます。
原則は次のとおりです。他の人が説明した内容を読むと、それは理にかなっているようです。
1. よく知られている問題として、通常のファイルに対する ajax 直接リクエストには、静的ページ、動的 web ページ、web サービス、または wcf のいずれであっても、ドメインを越えた不正アクセスの問題があります。クロスドメインリクエストであるため、許可されていません;
2. ただし、webページ上でjsファイルを呼び出す場合、クロスドメインであるかどうかに影響を受けないこともわかりました(それだけでなく、「src」属性を持つタグはすべてクロスであることもわかりました) -ドメイン機能 (
など)3. 現段階では、純粋な web 側 (activex コントロール、サーバー側プロキシ、および将来の html5 websocket は含まれません) を介してドメインを越えてデータにアクセスしたい場合、存在するのは 1 つだけであると判断できます。可能性があり、それはデータにリモート アクセスすることです。サーバーは、クライアントの呼び出しとさらなる処理のために、データを js 形式のファイルにロードしようとします。
4. 複雑なデータを簡潔に記述することができる、json と呼ばれる純粋な文字データ形式があることはすでにご存知です。さらに優れているのは、json も js によってネイティブにサポートされているため、クライアントはこの形式のデータをほとんど処理できることです。必要に応じて。 ;
5. これで、ソリューションの準備は完了です。web クライアントは、スクリプトを呼び出すのとまったく同じ方法で、クロスドメイン サーバー上で動的に生成された js 形式のファイル (通常は接尾辞として json を付けます) を呼び出します。サーバーが json ファイルを動的に生成する目的は、クライアントが必要とするデータをそのファイルにロードすることであることは明らかです。
6. クライアントは、json ファイルの呼び出しに成功すると、必要なデータを取得します。残りは、独自のニーズに従って処理および表示します。リモート データを取得するこの方法は、ajax に非常によく似ています。実際には同じではありません。
7. クライアントがデータを使用しやすくするために、非公式の送信プロトコルが徐々に形成されてきました。人々はそれを jsonp と呼んでいます。このプロトコルの重要なポイントの 1 つは、ユーザーがコールバック パラメーターをサーバーに渡せるようにすることです。このコールバック パラメータは json データをラップする関数名として使用されるため、クライアントは返されたデータを自動的に処理するように独自の関数をカスタマイズできます。
賢い開発者であれば、サーバーが提供する js スクリプトが動的に生成されている限り、呼び出し元はパラメーターを渡してサーバーに「ピースが欲しい」と伝えることができると簡単に考えることができます。 xxx 関数を呼び出す js コードを返してください。」すると、サーバーはクライアントのニーズに応じて js スクリプトを生成し、応答します。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title></title><script type="text/javascript">// 得到航班信息查询结果后的回调函数var flightHandler =function(data){ alert('你查询的航班结果是:piao价 '+ data.price +' 元,'+'余piao '+ data.tickets +' 张。'); }; // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)var url ="http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; // 创建script标签,设置其属性var script = document.createElement('script'); script.setAttribute('src', url); // 把script标签加入head,此时调用开始 //document.getElementsByTagName('head')[0].appendChild(script); </script></head><body></body></html> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Untitled Page</title><script type="text/javascript" src=jquery.min.js"></script><script type="text/javascript"> jQuery(document).ready(function(){ $.ajax({ type: "get", async: false, url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998", dataType: "jsonp", jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success: function(json){ alert('您查询到航班信息:piao价: '+ json.price +' 元,余piao: '+ json.tickets +' 张。'); }, error: function(){ alert('fail'); } }); }); </script></head><body></body></html>
それは少し奇妙ではありませんか?なぜ今回はflighthandler関数を書かなかったのでしょうか?そして実際にそれはうまくいきました!これは jquery の功績で、jquery が jsonp タイプの ajax を処理するとき (jquery は jsonp を ajax に分類することもありますが、実際には同じものではありません)、jsonp タイプの ajax を処理するときに、それを自動的に生成します。関数をコールバックして、success 属性メソッドが呼び出すデータを取り出すのは素晴らしいことではないでしょうか?