javascript - jsonp()




Worum geht es bei JSONP? (5)

Bevor Sie JSONP verstehen, müssen Sie das JSON-Format und XML kennen. Derzeit ist das am häufigsten verwendete Datenformat im Internet XML, aber XML ist sehr kompliziert. Es macht Benutzer unkomfortabel, eingebettete Webseiten zu verarbeiten.

Damit JavaScript auch als Datenverarbeitungsprogramm problemlos Daten austauschen kann, verwenden wir den Wortlaut nach JavaScript-Objekten und entwickelten ein einfaches Datenaustauschformat, das JSON ist. JSON kann als Daten oder als JavaScript-Programm verwendet werden.

JSON kann direkt in JavaScript eingebettet werden, mit ihnen können Sie bestimmte JSON-Programme direkt ausführen, aber aufgrund von Sicherheitseinschränkungen deaktiviert der Sandbox-Mechanismus des Browsers die Ausführung von domänenübergreifendem JSON-Code.

Um JSON nach der Ausführung übergeben zu können, haben wir einen JSONP entwickelt. JSONP umgeht die Sicherheitsgrenzen des Browsers mit JavaScript Callback-Funktionalität und dem <script> -Tag.

Kurz gesagt erklärt es, was JSONP ist, welches Problem es löst (wann es zu verwenden ist).

Diese Frage hat hier bereits eine Antwort:

Ich verstehe JSON, aber nicht JSONP. Das Wikipedia-Dokument zu JSON ist (war) das beste Suchergebnis für JSONP. Es sagt das:

JSONP oder "JSON with padding" ist eine JSON-Erweiterung, bei der ein Präfix als Eingabeargument des Aufrufs angegeben wird.

Hä? Welcher Anruf? Das ergibt für mich keinen Sinn. JSON ist ein Datenformat. Es gibt keinen Anruf.

Das zweite Suchergebnis stammt von einem Mann namens Remy , der über JSONP schreibt:

JSONP ist eine Skript-Tag-Injektion, bei der die Antwort vom Server an eine vom Benutzer angegebene Funktion übergeben wird.

Ich kann das irgendwie verstehen, aber es macht immer noch keinen Sinn.

Was ist JSONP? Warum wurde es erstellt (welches Problem löst es)? Und warum sollte ich es benutzen?

Nachtrag : Ich habe gerade eine neue Seite für JSONP auf Wikipedia erstellt; Es hat jetzt eine klare und gründliche Beschreibung von JSONP, basierend auf jvenema Antwort.


Ein einfaches Beispiel für die Verwendung von 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>

server.php

  <?php

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

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

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

    ?>    

JSONP erstellt ein "script" -Element (entweder in HTML-Markup oder über JavaScript in das DOM eingefügt), das an einen entfernten Datendienstort fragt. Die Antwort ist ein JavaScript, das in Ihren Browser geladen wird, wobei der Name der vordefinierten Funktion zusammen mit dem übergebenen Parameter die angeforderten JSON-Daten enthält. Wenn das Skript ausgeführt wird, wird die Funktion zusammen mit JSON-Daten aufgerufen, sodass die anfordernde Seite die Daten empfangen und verarbeiten kann.

Weitere Informationen finden Sie unter: https://blogs.sap.com/2013/07/15/secret-behind-jsonp/

clientseitiger Codeschnipsel

    <!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>

Serverseitiges Stück PHP-Code

<?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 . ")";
?>

JSONP ist eine großartige Möglichkeit, domainübergreifende Skriptfehler zu umgehen. Sie können einen JSONP-Dienst nur mit JS konsumieren, ohne auf der Serverseite einen AJAX-Proxy implementieren zu müssen.

Sie können den Dienst b1t.co verwenden , um zu sehen, wie es funktioniert. Dies ist ein kostenloser JSONP-Dienst, mit dem Sie Ihre URLs minimieren können. Hier ist die URL, die für den Service verwendet werden soll:

http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack]&url=[escapedUrlToMinify]

Zum Beispiel der Aufruf http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

würde zurückkehren

whateverJavascriptName({"success":true,"url":"http://google.com","shortUrl":"http://b1t.co/54"});

Und wenn das in Ihre js als src geladen wird, wird es automatisch whateverJavascriptName ausführen, die Sie als Callback-Funktion implementieren sollten:

function minifyResultsCallBack(data)
{
    document.getElementById("results").innerHTML = JSON.stringify(data);
}

Um den JSONP-Aufruf tatsächlich auszuführen, können Sie dies auf verschiedene Arten tun (einschließlich der Verwendung von jQuery), aber hier ist ein reines JS-Beispiel:

function minify(urlToMinify)
{
   url = escape(urlToMinify);
   var s = document.createElement('script');
   s.id = 'dynScript';
   s.type='text/javascript';
   s.src = "http://b1t.co/Site/api/External/MakeUrlWithGet?callback=resultsCallBack&url=" + url;
   document.getElementsByTagName('head')[0].appendChild(s);
}

Ein Schritt-für-Schritt-Beispiel und ein Jsonp-Webdienst zum Üben finden Sie unter: diesem Beitrag


JSONP ist wirklich ein einfacher Trick, um die gleiche Domänenrichtlinie XMLHttpRequest zu überwinden. (Wie Sie wissen, kann eine AJAX- Anfrage (XMLHttpRequest) nicht an eine andere Domain gesendet werden.)

Also - anstatt XMLHttpRequest zu verwenden, müssen wir Script- HTML-Tags verwenden, die normalerweise verwendet werden, um js-Dateien zu laden, damit js Daten von einer anderen Domain bekommen kann. Klingt komisch?

Sache ist - stellt sich heraus, dass Skript- Tags ähnlich wie XMLHttpRequest verwendet werden können ! Sieh dir das an:

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

Am Ende erhalten Sie ein Skript- Segment, das nach dem Laden der Daten aussieht:

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

Dies ist jedoch ein wenig unpraktisch, da wir dieses Array aus dem Skript- Tag holen müssen. JSONP- Entwickler haben entschieden, dass dies besser funktioniert (und es ist):

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

Beachten Sie die my_callback- Funktion dort drüben? Wenn also der JSONP- Server Ihre Anfrage empfängt und den Callback-Parameter findet, gibt er folgendes zurück:

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

Sehen Sie, wo der Gewinn ist: Jetzt bekommen wir einen automatischen Rückruf (my_callback), der ausgelöst wird, sobald wir die Daten bekommen haben.
Das ist alles, was es über JSONP zu wissen gibt: Es ist ein Callback und Skript-Tags.

HINWEIS: Dies sind einfache Beispiele für die Verwendung von JSONP. Hierbei handelt es sich nicht um produktionsfertige Skripts.

Einfaches JavaScript-Beispiel (einfacher Twitter-Feed mit JSONP)

<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>

Einfaches jQuery-Beispiel (einfacher Twitter-Feed mit JSONP)

<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 steht für JSON mit Padding . (sehr schlecht benannte Technik, da es wirklich nichts damit zu tun hat, was die meisten Leute als "Padding" bezeichnen würden.)





terminology