2334

JSONは理解できますが、JSONPは理解できません。ウィキペディアのJSONに関するドキュメントは、JSONPの上位の検索結果です。それはこれを言います:

JSONPまたは「JSONwithpadding」は、呼び出し自体の入力引数としてプレフィックスが指定されているJSON拡張機能です。

は?何と呼びますか?それは私には意味がありません。JSONはデータ形式です。電話はありません。

2番目の検索結果は、 JSONPについて次のように書いているRemyという名前の人からのものです。

JSONPはスクリプトタグインジェクションであり、サーバーからの応答をユーザー指定の関数に渡します。

私はそれをある程度理解することができますが、それでも意味がありません。


では、JSONPとは何ですか?なぜ作成されたのですか(どのような問題が解決されますか)?そして、なぜ私はそれを使うのでしょうか?


補遺:ウィキペディアにJSONPの新しいページを作成しました。jvenemaの回答に基づいて、JSONPの明確で完全な説明が追加されました。

4

10 に答える 10

2214

実際にはそれほど複雑ではありません...

あなたが domain にいて、 domainexample.comにリクエストしたいとしますexample.netそのためには、ドメインの境界を越える必要がありますが、これほとんどのブラウザランドでは禁止されています。

この制限を回避する 1 つのアイテムは<script>タグです。スクリプト タグを使用すると、ドメインの制限は無視されますが、通常の状況では、結果に対して実際には何もできずスクリプトが評価されるだけです。

を入力しJSONPます。JSONP が有効になっているサーバーにリクエストを送信するときは、サーバーにページに関する情報を少し伝える特別なパラメーターを渡します。そうすれば、サーバーはページが処理できる方法で応答を適切にまとめることができます。

たとえば、サーバーcallbackが JSONP 機能を有効にするために呼び出されるパラメーターを期待しているとします。次に、リクエストは次のようになります。

http://www.example.net/sample.aspx?callback=mycallback

JSONP がないと、次のような基本的な JavaScript オブジェクトが返される可能性があります。

{ foo: 'bar' }

ただし、JSONP では、サーバーが「callback」パラメーターを受け取ると、結果を少し異なる方法でラップして、次のように返します。

mycallback({ foo: 'bar' });

ご覧のとおり、指定したメソッドが呼び出されます。したがって、ページでコールバック関数を定義します。

mycallback = function(data){
  alert(data.foo);
};

そして、スクリプトがロードされると評価され、関数が実行されます。ほら、クロスドメインリクエスト!

また、JSONP の主要な問題の 1 つに注意する価値があります。それは、リクエストの多くの制御が失われることです。たとえば、適切なエラー コードを返す「適切な」方法はありません。その結果、タイマーを使用してリクエストなどを監視することになりますが、これは常に少し疑わしいものです。JSONRequestの命題は、クロスドメイン スクリプティングを許可し、セキュリティを維持し、リクエストを適切に制御できるようにする優れたソリューションです。

最近 (2015 年)、CORSは JSONRequest に対して推奨されるアプローチです。JSONP は、古いブラウザのサポートには引き続き役立ちますが、セキュリティへの影響を考えると、選択肢がない場合を除き、CORS の方が適しています。

于 2010-01-14T21:08:08.090 に答える
767

JSONPは、 XMLHttpRequestの同一ドメインポリシーを克服するための本当に簡単なトリックです。(ご存知のように、AJAX(XMLHttpRequest)リクエストを別のドメインに送信することはできません。)

つまり、XMLHttpRequestを使用する代わりに、jsが別のドメインからデータを取得するために、jsファイルをロードするために通常使用するスクリプトHTMLタグを使用する必要があります。変に聞こえますか?

スクリプトタグはXMLHttpRequestと同様の方法で使用できることがわかりました。これをチェックしてください:

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data';

データをロードすると、次のようなスクリプトセグメントが作成されます。

<script>
{['some string 1', 'some data', 'whatever data']}
</script>

ただし、スクリプトタグからこの配列をフェッチする必要があるため、これは少し不便です。そのため、 JSONPの作成者は、これがより適切に機能することを決定しました(そしてそれはそうです):

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data?callback=my_callback';

あそこのmy_callback関数に注目してください。したがって、JSONPサーバーがリクエストを受信して​​コールバックパラメーターを見つけると、プレーンなjs配列を返す代わりに、次のように返されます。

my_callback({['some string 1', 'some data', 'whatever data']});

利益がどこにあるかを確認します。データを取得するとトリガーされる自動コールバック(my_callback)を取得します。JSONP
について知っておくべきことはこれだけです。それはコールバックとスクリプトタグです。

注:これらはJSONPの使用法の簡単な例であり、本番環境に対応したスクリプトではありません。

基本的なJavaScriptの例(JSONPを使用した単純なTwitterフィード)

<html>
    <head>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
        <script>
        function myCallback(dataWeGotViaJsonp){
            var text = '';
            var len = dataWeGotViaJsonp.length;
            for(var i=0;i<len;i++){
                twitterEntry = dataWeGotViaJsonp[i];
                text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
            }
            document.getElementById('twitterFeed').innerHTML = text;
        }
        </script>
        <script type="text/javascript" src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script>
    </body>
</html>

基本的なjQueryの例(JSONPを使用した単純なTwitterフィード)

<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.ajax({
                    url: 'http://twitter.com/status/user_timeline/padraicb.json?count=10',
                    dataType: 'jsonp',
                    success: function(dataWeGotViaJsonp){
                        var text = '';
                        var len = dataWeGotViaJsonp.length;
                        for(var i=0;i<len;i++){
                            twitterEntry = dataWeGotViaJsonp[i];
                            text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
                        }
                        $('#twitterFeed').html(text);
                    }
                });
            })
        </script>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
    </body>
</html>


JSONPはJSONwithPaddingの略です。(ほとんどの人が「パディング」と考えるものとは実際には何の関係もないため、非常に貧弱な名前のテクニックです。)

于 2011-07-29T21:40:15.860 に答える
50

JSONP は、リモート データ サービスの場所に要求する「スクリプト」要素 (HTML マークアップまたは JavaScript を介して DOM に挿入) を構築することによって機能します。応答は、事前定義された関数の名前とともに、要求されている JSON データである渡されるパラメーターとともにブラウザーにロードされる JavaScript です。スクリプトが実行されると、JSON データと共に関数が呼び出され、要求元のページがデータを受信して​​処理できるようになります。

詳細については、 https ://blogs.sap.com/2013/07/15/secret-behind-jsonp/ をご覧ください。

クライアント側のコード スニペット

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <title>AvLabz - CORS : The Secrets Behind JSONP </title>
     <meta charset="UTF-8" />
    </head>
    <body>
      <input type="text" id="username" placeholder="Enter Your Name"/>
      <button type="submit" onclick="sendRequest()"> Send Request to Server </button>
    <script>
    "use strict";
    //Construct the script tag at Runtime
    function requestServerCall(url) {
      var head = document.head;
      var script = document.createElement("script");

      script.setAttribute("src", url);
      head.appendChild(script);
      head.removeChild(script);
    }

    //Predefined callback function    
    function jsonpCallback(data) {
      alert(data.message); // Response data from the server
    }

    //Reference to the input field
    var username = document.getElementById("username");

    //Send Request to Server
    function sendRequest() {
      // Edit with your Web Service URL
      requestServerCall("http://localhost/PHP_Series/CORS/myService.php?callback=jsonpCallback&message="+username.value+"");
    }    

  </script>
   </body>
   </html>

サーバー側の PHP コードの一部

<?php
    header("Content-Type: application/javascript");
    $callback = $_GET["callback"];
    $message = $_GET["message"]." you got a response from server yipeee!!!";
    $jsonResponse = "{\"message\":\"" . $message . "\"}";
    echo $callback . "(" . $jsonResponse . ")";
?>
于 2013-03-17T13:32:45.227 に答える
42

返された JSON オブジェクトの前にプレフィックスを追加するようにサーバーに要求できるためです。例えば

function_prefix(json_object);

ブラウザがevalJSON 文字列を式として「インライン化」するためです。このトリックにより、サーバーはクライアント ブラウザに直接 JavaScript コードを「注入」することが可能になり、「同一オリジン」制限を回避できます。

つまり、クロスドメインのデータ交換を実現できます。


通常、XMLHttpRequestクロスドメインのデータ交換を直接許可することはありません (同じドメイン内のサーバーを経由する必要があります)。

<script src="some_other_domain/some_data.js&prefix=function_prefix>` オリジンとは異なるドメインからデータにアクセスできます。


また、注目に値するのは、そのような「トリック」を試みる前にサーバーを「信頼できる」と見なす必要がある場合でも、オブジェクト形式などの変更の可能性による副作用を抑えることができるということです。JSON オブジェクトを受信するためにfunction_prefix(つまり、適切な js 関数) が使用されている場合、その関数は、返されたデータを受け入れる/さらに処理する前にチェックを実行できます。

于 2010-01-14T20:58:25.940 に答える
19
于 2013-03-28T15:59:04.267 に答える
14

JSONP の使用法の簡単な例。

client.html

    <html>
    <head>
   </head>
     body>


    <input type="button" id="001" onclick=gO("getCompany") value="Company"  />
    <input type="button" id="002" onclick=gO("getPosition") value="Position"/>
    <h3>
    <div id="101">

    </div>
    </h3>

    <script type="text/javascript">

    var elem=document.getElementById("101");

    function gO(callback){

    script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'http://localhost/test/server.php?callback='+callback;
    elem.appendChild(script);
    elem.removeChild(script);


    }

    function getCompany(data){

    var message="The company you work for is "+data.company +"<img src='"+data.image+"'/   >";
    elem.innerHTML=message;
}

    function getPosition(data){
    var message="The position you are offered is "+data.position;
    elem.innerHTML=message;
    }
    </script>
    </body>
    </html>

サーバー.php

  <?php

    $callback=$_GET["callback"];
    echo $callback;

    if($callback=='getCompany')
    $response="({\"company\":\"Google\",\"image\":\"xyz.jpg\"})";

    else
    $response="({\"position\":\"Development Intern\"})";
    echo $response;

    ?>    
于 2014-06-06T06:45:37.353 に答える
8

JSONP を理解する前に、JSON 形式と XML を理解する必要があります。現在、Web で最も頻繁に使用されるデータ形式は XML ですが、XML は非常に複雑です。Web ページに埋め込まれた処理をユーザーに不便にさせます。

データ処理プログラムとしても JavaScript を簡単にデータ交換できるように、JavaScript のオブジェクトに応じた文言を使い、簡単なデータ交換フォーマットである JSON を開発しました。JSON は、データとして、または JavaScript プログラムとして使用できます。

JSON は JavaScript に直接埋め込むことができ、それらを使用して特定の JSON プログラムを直接実行できますが、セキュリティ上の制約により、ブラウザーのサンドボックス メカニズムはクロスドメイン JSON コードの実行を無効にします。

実行後にJSONを渡すことができるようにするために、JSONPを開発しました。JSONP は、JavaScript コールバック機能と < script > タグを使用してブラウザーのセキュリティ制限をバイパスします。

つまり、JSONP とは何か、JSONP が解決する問題 (いつ使用するか) を簡単に説明します。

于 2015-12-08T04:02:30.803 に答える