Vraag Waar gaat JSONP eigenlijk allemaal over?


Ik begrijp JSON, maar niet JSONP. Wikipedia's document over JSON is (was) het beste zoekresultaat voor JSONP. Het zegt dit:

JSONP of "JSON met opvulling" is een JSON-extensie waarin een voorvoegsel is opgegeven als invoerargument voor de aanroep zelf.

Huh? Welke oproep? Dat slaat nergens op. JSON is een gegevensformaat. Er is geen oproep.

De 2e zoekresultaat is van een man met de naam Remy, wie schrijft dit over JSONP:

JSONP is een scripttag-injectie die het antwoord van de server doorgeeft aan een door de gebruiker gespecificeerde functie.

Ik kan dat soort dingen begrijpen, maar het slaat nog steeds nergens op.


Dus wat is JSONP? Waarom is het gemaakt (welk probleem lost het op)? En waarom zou ik het gebruiken?


bijvoegsel: Ik heb zojuist gemaakt een nieuwe pagina voor JSONP op Wikipedia; het heeft nu een duidelijke en grondige beschrijving van JSONP, gebaseerd op jvenemahet antwoord.


1833
2018-01-14 20:53


oorsprong


antwoorden:


Het is eigenlijk niet zo ingewikkeld ...

Stel dat u op domain example.com bent en een verzoek wilt indienen bij domain.net. Om dit te doen, moet je de grenzen van het domein overschrijden, een nee-nee in de meeste browserlands.

Het enige item dat deze beperking omzeilt, is <script> -tags. Wanneer u een scripttag gebruikt, wordt de domeinbeperking genegeerd, maar onder normale omstandigheden kunt u dit niet echt do alles met de resultaten, het script wordt gewoon geëvalueerd.

Voer JSONP in. Wanneer u uw aanvraag indient bij een server waarvoor JSONP is ingeschakeld, geeft u een speciale parameter door die de server een beetje over uw pagina vertelt. Op die manier is de server in staat om zijn reactie mooi in te pakken op een manier die uw pagina aankan.

Stel dat de server een parameter verwacht die "callback" wordt genoemd, om zijn JSONP-mogelijkheden in te schakelen. Dan zou uw verzoek er als volgt uitzien:

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

Zonder JSONP zou dit een standaard JavaScript-object kunnen retourneren, zoals zo:

{ foo: 'bar' }

Als JSONP echter de parameter 'callback' ontvangt, wordt het resultaat iets anders ingepakt en wordt zoiets als dit weergegeven:

mycallback({ foo: 'bar' });

Zoals u kunt zien, zal het nu de methode oproepen die u hebt opgegeven. Dus op uw pagina definieert u de callback-functie:

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

En nu, wanneer het script is geladen, wordt het geëvalueerd en wordt uw functie uitgevoerd. Voila, aanvragen voor meerdere domeinen!

Het is ook de moeite waard om het enige belangrijke probleem met JSONP te vermelden: u verliest veel controle over het verzoek. Er is bijvoorbeeld geen 'leuke' manier om de juiste foutcodes terug te krijgen. Als gevolg hiervan gebruik je timers om het verzoek te controleren, enz., Wat altijd een beetje verdacht is. De propositie voor JSONRequest is een geweldige oplossing voor het toestaan ​​van cross-domein scripting, het onderhouden van de beveiliging en het toestaan ​​van de juiste controle van het verzoek.

Deze dagen (2015), CORS is de aanbevolen benadering versus JSONRequest. JSONP is nog steeds nuttig voor oudere browsers, maar gezien de veiligheidsimplicaties is CORS de betere keuze, tenzij je geen keus hebt.


1795
2018-01-14 21:08



JSONP is echt een simpele truc om het te overwinnen XMLHttpRequest hetzelfde domeinbeleid. (Zoals je weet kan iemand niet verzenden AJAX (XMLHttpRequest) aanvraag voor een ander domein.)

Dus - in plaats van gebruiken XMLHttpRequest we moeten gebruiken script HTML-tags, degene die u gewoonlijk gebruikt om js-bestanden te laden, zodat js gegevens van een ander domein kan ophalen. Klinkt raar?

Het is - blijkt script tags kunnen op een vergelijkbare manier worden gebruikt XMLHttpRequest! Bekijk dit:

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

Je zult eindigen met een script segment dat er zo uitziet nadat het de gegevens heeft geladen:

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

Dit is echter een beetje onhandig, omdat we deze array moeten ophalen script label. Zo JSONP makers hebben besloten dat dit beter zal werken (en dat is het ook):

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

Let op de my_callback werken daar? Dus wanneer JSONP server ontvangt uw aanvraag en vindt de callback-parameter - in plaats van de gewone js-array te retourneren, wordt dit geretourneerd:

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

Zie waar de winst is: nu krijgen we automatische callback (my_callback) die wordt geactiveerd zodra we de gegevens hebben ontvangen.
Dat is alles wat er te weten valt JSONP: het is een callback- en script-tags.

OPMERKING: dit zijn eenvoudige voorbeelden van JSONP-gebruik, dit zijn geen scripts die klaar zijn voor productie.

Eenvoudig JavaScript-voorbeeld (eenvoudige Twitter-feed met 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>

Eenvoudig jQuery-voorbeeld (eenvoudige Twitter-feed met 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 betekent JSON met opvulling. (zeer slecht genoemde techniek omdat het echt niets te maken heeft met wat de meeste mensen zouden denken als "opvulling".)


640
2017-07-29 21:40



JSONP werkt door een "script" -element te construeren (hetzij in HTML-markup of ingevoegd in de DOM via JavaScript), dat vraagt ​​naar een locatie op de externe gegevensservice. Het antwoord is een javascript geladen op uw browser met de naam van de vooraf gedefinieerde functie, samen met de parameter die wordt doorgegeven dat de JSON-gegevens worden gevraagd. Wanneer het script wordt uitgevoerd, wordt de functie samen met JSON-gegevens opgeroepen, zodat de verzoekende pagina de gegevens kan ontvangen en verwerken.

Voor meer informatie bezoek:  https://blogs.sap.com/2013/07/15/secret-behind-jsonp/

client-codefragment

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

Server side stuk van 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 . ")";
?>

38
2018-03-17 13:32



Omdat u de server kunt vragen een voorvoegsel toe te voegen aan het geretourneerde JSON-object. bijv

function_prefix(json_object);

zodat de browser dit kan doen eval "inline" de JSON-reeks als een uitdrukking. Deze truc maakt het voor de server mogelijk om javascript-code rechtstreeks in de clientbrowser te "injecteren" en dit met het omzeilen van de beperkingen van "dezelfde oorsprong".

Met andere woorden, je kunt hebben gegevensuitwisseling tussen verschillende domeinen.


Normaal gesproken, XMLHttpRequest staat geen directe uitwisseling van gegevens tussen verschillende domeinen toe (men moet door een server in hetzelfde domein gaan), terwijl:

<script src="some_other_domain/some_data.js&prefix=function_prefix> `u kunt toegang krijgen tot gegevens uit een ander domein dan uit de bron.


Ook vermeldenswaard: hoewel de server als "vertrouwd" moet worden beschouwd voordat een dergelijk "trick" wordt geprobeerd, kunnen de bijwerkingen van mogelijke verandering in objectindeling enz. Worden ingeperkt. Als een function_prefix(d.w.z. een goede js-functie) wordt gebruikt om het JSON-object te ontvangen, de genoemde functie kan controles uitvoeren voordat de geretourneerde gegevens worden geaccepteerd / verder verwerkt.


37
2018-01-14 20:58



JSONP is een prima manier om cross-domein scriptingfouten te omzeilen. U kunt een JSONP-service puur gebruiken met JS zonder een AJAX-proxy aan de serverzijde te hoeven implementeren.

U kunt de b1t.co dienst om te zien hoe het werkt. Dit is een gratis JSONP-service waarmee u uw URL's verkleint. Hier is de URL die u voor de service kunt gebruiken:

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

Bijvoorbeeld de oproep, http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

zou terugbrengen

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

En dus, wanneer dat in je js wordt geladen als een src, zal het automatisch die javascriptnaam uitvoeren die je zou moeten implementeren als je callback-functie:

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

Om de JSONP-aanroep daadwerkelijk te doen, kunt u dit op verschillende manieren doen (inclusief het gebruik van jQuery) maar hier is een puur JS-voorbeeld:

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);
}

Een stapsgewijs voorbeeld en een jsonp webservice om te oefenen is beschikbaar op: deze post


17
2018-03-28 15:59



Een eenvoudig voorbeeld voor het gebruik van 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;

    ?>    

10
2018-06-06 06:45



Voordat u JSONP begrijpt, moet u het JSON-formaat en XML kennen. Momenteel is XML het meest gebruikte gegevensformaat op het web, maar XML is erg gecompliceerd. Het maakt gebruikers ongelegen om te verwerken ingebed in webpagina's.

Om ervoor te zorgen dat JavaScript eenvoudig gegevens kan uitwisselen, zelfs als het gegevensverwerkingsprogramma, gebruiken we de formulering volgens JavaScript-objecten en hebben we een eenvoudig gegevensuitwisselingsformaat ontwikkeld, namelijk JSON. JSON kan worden gebruikt als gegevens of als een JavaScript-programma.

JSON kan direct in JavaScript worden ingesloten, met behulp van deze kunt u een bepaald JSON-programma direct uitvoeren, maar vanwege beveiligingsbeperkingen schakelt het Sandbox-mechanisme in de webserver de uitvoering van JSON-code tussen verschillende domeinen uit.

Om JSON na de uitvoering te kunnen doorgeven, hebben we een JSONP ontwikkeld. JSONP omzeilt de beveiligingslimieten van de browser met JavaScript Callback-functionaliteit en de <script> -tag.

Dus in het kort wordt uitgelegd wat JSONP is, welk probleem het oplost (wanneer het te gebruiken).


9
2017-12-08 04:02