クロスドメインリクエストデータのソリューションには主に次のソリューションが含まれます:
JSONP方式 表单POST方式 服务器代理 Html5的XDomainRequest Flash request
個別の手順:
1. JSONP:
直感的な理解:
クライアントに関数を動的に登録することです
function a(data) を呼び出し、その関数名をサーバーに渡します。サーバーは a({/*json*/}) をクライアントに返して実行するため、クライアントの
が呼び出されます。関数 a(データ) により、クロスドメインが実現されます。
誕生の背景:
1. Ajax は通常のファイルを直接リクエストするため、静的ページ、動的 Web ページ、Web サービス、または WCF であるかどうかに関係なく、許可なくクロスドメイン アクセスが発生するという問題があります。ドメインリクエストは機能しません。
2. ただし、Web ページ上で js ファイルを呼び出す場合は、この
の影響を受けません。3. さらに推進すると、Src 属性を持つすべてのタグに次のようなクロスドメイン機能があることがわかりました。
4. したがって、現時点で純粋な Web 側 (ActiveX コントロール、サーバー側プロキシ、将来の HTML5 に属する WebSocket などは含まれません) を通じてデータにクロスドメインにアクセスしたい場合は、次のメソッド: リモート サーバー上で、クライアントの呼び出しとさらなる処理のために、データを js 形式のテキストにロードしてみます。
5. JSON は純粋な文字データ形式であり、js でネイティブにサポートできます。
6. 解決策は次のとおりです。Web クライアントは、スクリプトを呼び出すのとまったく同じ方法で、クロスドメイン サーバー上で動的に生成された js 形式ファイル (通常は接尾辞として json が付きます) を呼び出します。
7. クライアントは json ファイルの呼び出しに成功すると、必要なデータを取得し、残りは独自のニーズに従って処理します。
8 クライアントがデータを使用しやすくするために、jsonp と呼ばれる非公式の送信プロトコルが徐々に形成されてきました。このプロトコルの重要な点は、ユーザーがコールバック パラメーターをサーバーに渡すことを許可し、サーバーがデータを返すときに、このコールバック パラメーターを関数名として使用して JSON データをラップし、クライアントがそのデータをカスタマイズできるようにすることです。返されたデータを処理する独自の関数。
詳細な実装:
jQuery、extjs、または jsonp をサポートするその他のフレームワークのいずれであっても、舞台裏で行われる作業は同じです。クライアントでの jsonp の実装について順を追って説明します。
1. クロスドメイン js ファイル内のコード (もちろん Web スクリプトのセキュリティ ポリシーに準拠している) であっても、Web ページは無条件に実行できることがわかっています。
リモートサーバーremoteserver.comのルートディレクトリには、次のようなremote.jsファイルコードがあります:
alert('私はリモートファイルです');
ローカルサーバー localserver.com には、次のような jsonp.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></title> <script type="text/javascript" src="http://remoteserver.com/remote.js"></script> </head> <body> </body> </html>
クロスドメイン呼び出しが成功したことを示すプロンプト ウィンドウがページにポップアップ表示されることは間違いありません。
2. 次に、jsonp.html ページで関数を定義し、remote.js にデータを渡して呼び出します。
jsonp.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></title> <script type="text/javascript"> var localHandler = function(data){ alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result); }; </script> <script type="text/javascript" src="http://remoteserver.com/remote.js"></script> </head> <body> </body> </html>
remote.js ファイルのコードは次のとおりです:
localHandler({"result":"私はリモート js によってもたらされたデータです"});
実行後に結果を確認すると、ページにプロンプト ウィンドウが正常に表示され、クロスドメイン リモート JS によってローカル関数が正常に呼び出され、リモート JS によってもたらされたデータも受信したことが示されます。クロスドメインのリモートデータ取得の目的は基本的に達成されたので非常に満足していますが、リモート js に呼び出す必要があるローカル関数の名前をどのように知らせるのかという別の疑問が生じます。結局のところ、jsonp サーバーは多くのサービス オブジェクトに直面する必要があり、これらのサービス オブジェクトのローカル機能は異なります。下を見てみましょう。
3. 賢い開発者は、サーバーによって提供される JS スクリプトが動的に生成される限り、呼び出し元はパラメーターを渡してサーバーに「XXX 関数を呼び出す JS コードが必要なので、それを返してください」と伝えることができると簡単に考えることができます。 to me」と指定すると、サーバーは js スクリプトを生成し、クライアントのニーズに応じて応答できます。
jsonp.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></title> <script type="text/javascript"> // 得到航班信息查询结果后的回调函数 var flightHandler = function(data){ alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + 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>
今回はコードが大幅に変更されており、リモート js ファイルを直接記述することはなくなりましたが、これは jsonp クライアント実装の核心部分でもあります。 jsonp呼び出しのプロセス全体。
コード パラメータが呼び出し元の URL に渡されて、チェックしたいのは CA1998 便の情報であることをサーバーに伝え、コールバック パラメータはローカル コールバック関数の名前が FlightHandler であることをサーバーに伝えていることがわかります。クエリ結果を渡します この関数を呼び出します。
flightHandler({ "code": "CA1998", "price": 1780, "tickets": 5 });
我们看到,传递给flightHandler函数的是一个json,它描述了航班的基本信息。运行一下页面,成功弹出提示窗口,jsonp的执行全过程顺利完成!
4、到这里为止的话,相信你已经能够理解jsonp的客户端实现原理了吧?剩下的就是如何把代码封装一下,以便于与用户界面交互,从而实现多次和重复调用。
什么?你用的是jQuery,想知道jQuery如何实现jsonp调用?好吧,那我就好人做到底,再给你一段jQuery使用jsonp的代码(我们依然沿用上面那个航班信息查询的例子,假定返回jsonp结果不变):
OK,服务器很聪明,这个叫做flightResult.aspx的页面生成了一段这样的代码提供给jsonp.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('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。'); }, error: function(){ alert('fail'); } }); }); </script> </head> <body> </body> </html>
是不是有点奇怪?为什么我这次没有写flightHandler这个函数呢?而且竟然也运行成功了!哈哈,这就是jQuery的功劳了,jquery在处理jsonp类型的ajax时(还是忍不住吐槽,虽然jquery也把jsonp归入了ajax,但其实它们真的不是一回事儿),自动帮你生成回调函数并把数据取出来供success属性方法来调用,是不是很爽呀?
以上所述就是本文的全部内容了,希望大家能够喜欢。