JSONP
はパディング付きのJSON
です。
JSONとは何か、そしてそれを jQuery.getJSON()
と一緒に使用する方法を理解しています。しかし、JSONPを導入するとき、私はcallback
の概念を理解していません。
これがどのように機能するかを誰かが私に説明できますか?
この答えは6歳以上です。 JSONPの概念とアプリケーションは変わっていませんが(つまり答えの詳細はまだ有効です)、 可能であればCORSを使うようにしてください (つまりあなたの server またはJSONPとして、 API がサポートされています。 ブラウザサポート で十分です) 固有のセキュリティリスクがあります 。
JSONP(JSON with Padding)は、Webブラウザでクロスドメインポリシーを回避するために一般的に使用されている方法です。 (ブラウザによって異なるサーバー上にあると認識されているWebページへのAJAX要求を行うことは許可されていません。)
JSONとJSONPは、クライアントとサーバーで動作が異なります。 JSONPリクエストはXMLHTTPRequest
および関連するブラウザメソッドを使ってディスパッチされることはありません。代わりに、ソースがターゲットURLに設定されている<script>
タグが作成されます。その後、このスクリプトタグがDOMに追加されます(通常は<head>
要素内)。
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// success
};
};
xhr.open("GET", "somewhere.php", true);
xhr.send();
var tag = document.createElement("script");
tag.src = 'somewhere_else.php?callback=foo';
document.getElementsByTagName("head")[0].appendChild(tag);
JSONレスポンスとJSONPレスポンスの違いは、JSONPレスポンスオブジェクトは引数としてコールバック関数に渡されることです。
{ "bar": "baz" }
foo( { "bar": "baz" } );
これが、JSONPリクエストにcallback
パラメータが含まれていることを示しているためです。これにより、サーバーはレスポンスをラップする関数の名前を知ることができます。
この関数は、グローバルスコープに存在している必要があります<script>
タグはブラウザによって評価されます(要求が完了した後)。
JSON応答の処理とJSONP応答の処理の間で注意すべきもう1つの違いは、JSON応答の解析エラーがtry/catchステートメントでresponseTextを評価する試みをラップすることによって検出される可能性があることです。 JSONPレスポンスの性質上、レスポンス内の解析エラーにより、キャッチできないJavaScript解析エラーが発生します。
どちらの形式でも、要求を開始する前にタイムアウトを設定し、応答ハンドラでタイムアウトをクリアすることによってタイムアウトエラーを実装できます。
JSONPリクエストを行うためにjQueryを使用することの有用性は、jQueryがバックグラウンドですべての作業を行うことです。
デフォルトでjQueryはあなたのAJAXリクエストのURLに&callback=?
を含めることを要求します。 jQueryはあなたが指定したsuccess
関数を取り、それにユニークな名前を割り当て、そしてグローバルスコープでそれを公開します。それはそれからそれが割り当てた名前で?
の疑問符&callback=?
を置き換えます。
以下はレスポンスオブジェクト{ "bar" : "baz" }
を仮定しています
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("output").innerHTML = eval('(' + this.responseText + ')').bar;
};
};
xhr.open("GET", "somewhere.php", true);
xhr.send();
function foo(response) {
document.getElementById("output").innerHTML = response.bar;
};
var tag = document.createElement("script");
tag.src = 'somewhere_else.php?callback=foo';
document.getElementsByTagName("head")[0].appendChild(tag);
次のようなJSONデータを提供するURLがあるとします。
{'field': 'value'}
...そして、あなたがコールバック関数名 'myCallback'を渡したJSONPを使用することを除いて同様のURLを持っていました(通常 'callback'と呼ばれるクエリパラメータを与えることによって行われます、例えばhttp://example.com/dataSource?callback=myCallback
)それからそれは戻ります:
myCallback({'field':'value'})
...これは単なるオブジェクトではありませんが、実際には実行可能なコードです。そのため、ページの他の場所でmyFunction
という関数を定義してこのスクリプトを実行すると、URLからのデータを使用して呼び出されます。
これについての素晴らしいことは、スクリプトタグを作成し、あなたのURL(callback
パラメータを付けて)をsrc
属性として使うことができ、ブラウザがそれを実行することです。つまり、ブラウザではページのドメイン以外のソースからスクリプトタグを実行できるため、 'same-Origin'セキュリティポリシーを回避できます。
これがあなたがajaxリクエストをするときにjQueryがすることです(dataType
プロパティの値として 'jsonp'と共に .ajax
を使う)。例えば。
$.ajax({
url: 'http://example.com/datasource',
dataType: 'jsonp',
success: function(data) {
// your code to handle data here
}
});
ここでは、jQueryがコールバック関数名とクエリパラメータを処理し、APIを他のajax呼び出しと同じにします。しかし、他の種類のajaxリクエストとは異なり、前述のように、あなたはあなたのページと同じOriginからデータを取得することに制限されていません。
JSONPはブラウザの 同一Originポリシー を回避する方法です。どうやって?このような:
ここでの目標は、応答の中の名前にotherdomain.com
とalert
を要求することです。通常はAJAXリクエストを行います。
$.get('otherdomain.com', function (response) {
var name = response.name;
alert(name);
});
ただし、要求は別のドメインに送信されるため、機能しません。
<script>
タグを使ってリクエストを行うこともできます。 <script src="otherdomain.com"></script>
と$.get('otherdomain.com')
の両方が同じリクエストを行います。
GET otherdomain.com
Q:しかし<script>
タグを使用した場合、どうやってアクセスできますか? alert
にしたい場合は、アクセスする必要があります。
A:ええと、できません。しかし、これが可能なことです - レスポンスを使用する関数を定義してから、レスポンスを引数として関数を呼び出すJavaScriptで応答するようにサーバーに指示します。
Q:しかし、もしサーバーが私たちのためにこれをしないで、そして私たちにJSONを返すことを喜んでだけ行うならばどうでしょうか?
A:それならそれを使うことはできません。 JSONPは協力することをサーバに要求します。
Q:<script>
タグを使わなければならないのは醜いです。
A:jQueryのようなライブラリ より良くする 。例:
$.ajax({
url: "http://otherdomain.com",
jsonp: "callback",
dataType: "jsonp",
success: function( response ) {
console.log( response );
}
});
動的に<script>
タグのDOM要素を作成することによって機能します。
Q:<script>
タグはGETリクエストのみを行います - POSTリクエストをしたい場合はどうしますか?
A:それならJSONPは私達のために働きません。
Q:大丈夫です、GETリクエストをしたいだけです。 JSONPはすごいです、そして私はそれを使いに行くつもりです - ありがとう!
A:実際、それほど素晴らしいことではありません。それは本当に単なるハックです。そしてそれは 最も安全ではない 使うべきこと。 CORSが利用可能になったので、可能ならいつでもそれを使うべきです。
私はまた、そのトピックを非常に明確かつ簡単に説明している便利な記事を見つけました。リンクは JSONP
注目に値する点は次のとおりです。
作業は次のとおりです。
<script src="url?callback=function_name">
はhtmlコードに含まれています