TL; DR
JSONPは、別のサーバー(別のオリジン*)からJSONデータを取得することを禁止するセキュリティ制限を回避するために考案された古いトリックです。
トリックは<script>
、その場所からJSONを要求するタグを使用することで{ "user":"Smith" }
機能します。例:が、実際のJSONP(「JSON with Padding」)の関数にラップされています。
peopleDataJSONP({"user":"Smith"})
この形式で受信すると、peopleDataJSONP
関数内でデータを使用できます。JSONPは悪い習慣です。使用しないでください(以下をお読みください)
問題
ナビゲートしていてourweb.com
、JSONデータ(または実際の生データ)をから取得したいとしますanotherweb.com
。GETリクエスト(XMLHttpRequest
、fetch
呼び出し$.ajax
など)を使用する場合、ブラウザはこの醜いエラーで許可されていないことを通知します。
必要なデータを取得するにはどうすればよいですか?まあ、<script>
タグはこのサーバー全体(origin *)の制限を受けません!そのため、jQueryやGoogleマップなどのライブラリをCDNなどの任意のサーバーからエラーなしでロードできます。
重要なポイント:考えてみれば、これらのライブラリは実際の実行可能なJSコード(通常、すべてのロジックが内部にある大規模な関数)です。しかし生データ?JSONデータはコードではありません。実行するものは何もありません。単なるデータです。
したがって、貴重なデータを処理または操作する方法はありません。ブラウザは<script>
タグが指すデータをダウンロードし、処理する際に当然のように文句を言うでしょう:
{"user":"Smith"}
我々がロードしたこのがらくたはwtf ですか?コードではありません。計算できません、構文エラーです!
JSONPハック
そのデータを利用する古い/ハッキーな方法?何らかのロジックを使用してサーバーに送信する必要があるので、サーバーが読み込まれると、ブラウザーのコードでこのデータを使用できるようになります。したがって、外部サーバーはJS関数内でJSONデータを送信します。データ自体は、その関数の入力として設定されます。次のようになります。
peopleDataJSONP({"user":"Smith"})
これにより、ブラウザが文句なしに解析できるJSコードになります。jQueryライブラリの場合とまったく同じです。これを実現するために、クライアントはJSONP対応のサーバーに「要求」します。通常は次のようにします。
<script src="https://anotherweb.com/api/data-from-people.json?myCallback=peopleDataJSONP"></script>
私たちのブラウザーはその関数名を持つJSONPを受け取るので、次のように、コード内に同じ名前の関数が必要です。
const peopleDataJSONP = function(data){
alert(data.user); // "Smith"
}
またはこのように、同じ結果:
function peopleDataJSONP(data){
alert(data.user); // "Smith"
}
ブラウザはJSONPをダウンロードして実行し、関数を呼び出しdata
ます。ここで、引数はJSONです。これで、データを好きなように処理できます。
JSONPを使用せず、CORSを使用
JSONPは、いくつかの欠点があるクロスサイトハックです。
- GETリクエストのみ実行できます
- これは単純なスクリプトタグによってトリガーされるGETリクエストであるため、有用なエラーや進捗情報は取得されません
- 悪意のあるペイロードに変更される可能性のあるクライアントJSコードでの実行など、いくつかのセキュリティ上の懸念もあります
- JSONデータの問題のみを解決しますが、Same-Originセキュリティポリシーは他のデータ(WebFonts、drawImage()で描画された画像/ビデオ)に適用されます
- それは非常にエレガントでも可読でもありません。
要点は、最近は使用する必要がないことです。
JSONPは別のサーバーからJSONデータを取得するトリックですが、他の種類のクロスサイトのものが必要な場合は、同じセキュリティ原則(Same-Origin)に違反します。
ここでCORSについて読む必要がありますが、その要点は次のとおりです。
クロスオリジンリソースシェアリング(CORS)は、追加のHTTPヘッダーを使用して、あるオリジンで実行されているWebアプリケーションに、別のオリジンから選択されたリソースへのアクセスを許可するようにブラウザーに指示するメカニズムです。Webアプリケーションは、独自のオリジン(ドメイン、プロトコル、またはポート)を持つリソースを要求すると、クロスオリジンHTTP要求を実行します。
* originは、プロトコル、ポート、ホストの 3つの要素で定義されます。したがって、たとえば、(異なるプロトコル)および(異なるポート)とは明らかにhttps://web.com
異なる起源であり、明らかに(異なるホスト)http://web.com
https://web.com:8081
https://thatotherweb.net