Pytanie O co chodzi w JSONP?


Rozumiem JSON, ale nie JSONP. Dokument Wikipedii o JSON jest (był) najwyższym wynikiem wyszukiwania dla JSONP. Mówi to:

JSONP lub "JSON with padding" jest rozszerzeniem JSON, w którym prefiks jest określony jako argument wejściowy samego wywołania.

Huh? Jakie połączenie? To nie ma dla mnie żadnego sensu. JSON to format danych. Nie ma połączenia.

The Drugi wynik wyszukiwania pochodzi od jakiegoś faceta Remy, który pisze o JSONP:

JSONP to iniekcja znacznika skryptu, przekazująca odpowiedź z serwera do określonej przez użytkownika funkcji.

Mogę to zrozumieć, ale to wciąż nie ma sensu.


Czym jest JSONP? Dlaczego został stworzony (jaki problem rozwiązuje)? I dlaczego miałbym go używać?


Uzupełnienie: Właśnie stworzyłem nowa strona dla JSONP na Wikipedii; ma teraz jasny i dokładny opis JSONP, na podstawie jvenemaodpowiedź.


1835
2018-01-14 20:53


pochodzenie


Skaffman, czy biorę to z twojego tonu, że jesteś tym, który usunął całkowicie rozsądne pytania z WIKIpedia? Bez dodawania niczego lub ulepszania? Jak to jest "wandalizm" zadać pytanie. Do licha. I tak, w tej chwili zamierzam ulepszyć stronę wikipedii z informacjami, które dostarczył jvenema. - Cheeso
Świetnie, jeśli masz lepsze informacje, dodaj je. Ale nie zadawaj pytań na wikipedii, dodajesz fakty. - skaffman
Dla rekordu NIE używaj JSONP, jeśli nie ufasz serwerowi, z którym rozmawiasz w 100%. Jeśli zostanie naruszony, twoja strona internetowa zostanie w niewielkim stopniu naruszona. - ninjagecko
Zauważ także, że JSONP może zostać porwany jeśli nie jest poprawnie zaimplementowany. - Pacerier
Dlaczego to pytanie jest oznaczane jako duplikat, gdy pytanie to jest "duplikatem" pytania o 10 miesięcy po ten? - jvenema


Odpowiedzi:


W rzeczywistości nie jest to zbyt skomplikowane ...

Załóżmy, że jesteś w domenie example.com i chcesz wysłać żądanie do domeny example.net. Aby to zrobić, musisz przekroczyć granice domeny, co nie jest możliwe w większości obszarów przeglądarek.

Jedynym elementem pomijającym to ograniczenie są znaczniki <script>. Kiedy używasz znacznika skryptu, ograniczenie domeny jest ignorowane, ale w normalnych okolicznościach tak naprawdę nie możesz zrobić cokolwiek z wynikami, skrypt jest oceniany.

Wprowadź JSONP. Po wysłaniu żądania do serwera z włączoną obsługą JSONP, przekazujesz specjalny parametr, który trochę informuje serwer o Twojej stronie. W ten sposób serwer jest w stanie ładnie podsumować swoją odpowiedź w sposób, w jaki strona może obsłużyć.

Na przykład, powiedzmy, że serwer oczekuje parametru o nazwie "wywołanie zwrotne", aby włączyć jego funkcje JSONP. Twoja prośba będzie wyglądać następująco:

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

Bez JSONP może to zwrocić kilka podstawowych obiektów JavaScript, takich jak:

{ foo: 'bar' }

Jednak w przypadku JSONP, gdy serwer odbiera parametr "oddzwanianie", nieco inaczej zawija wynik, zwracając coś takiego:

mycallback({ foo: 'bar' });

Jak widać, będzie teraz wywoływał określoną metodę. Więc na twojej stronie definiujesz funkcję zwrotną:

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

A teraz, po wczytaniu skryptu, zostanie on oceniony, a twoja funkcja zostanie wykonana. Voila, żądania między domenami!

Warto również zwrócić uwagę na jeden istotny problem związany z JSONP: tracisz kontrolę nad żądaniem. Na przykład nie ma "miłego" sposobu na odzyskanie poprawnych kodów błędów. W rezultacie kończy się używanie liczników czasu do monitorowania żądania itp., Co zawsze jest trochę podejrzane. Propozycja dla JSONRequest to świetne rozwiązanie pozwalające na wykonywanie skryptów krzyżowych, utrzymywanie bezpieczeństwa i pozwalające na właściwą kontrolę nad żądaniem.

Te dni (2015), CORS jest zalecanym podejściem do JSONRequest. JSONP jest nadal przydatny dla starszych przeglądarek, ale ze względu na bezpieczeństwo, chyba że nie masz wyboru, CORS to lepszy wybór.


1796
2018-01-14 21:08



Należy pamiętać, że korzystanie z JSONP ma pewne implikacje dla bezpieczeństwa. Ponieważ JSONP jest naprawdę javascript, może zrobić wszystko inne, co javascript może zrobić, więc musisz zaufać dostawcy danych JSONP. Napisałem o tym blogu na blogu: erlend.oftedal.no/blog/?blogid=97 - Erlend
Czy w JSONP rzeczywiście występuje jakieś nowe implikacje bezpieczeństwa, którego nie ma w tagu <script>? Za pomocą znacznika skryptu przeglądarka domyślnie ufa serwerowi dostarczając nieszkodliwy skrypt Javascript, który przeglądarka ślepo ocenia. czy JSONP zmienia ten fakt? Wygląda na to, że tak nie jest. - Cheeso
Nie, nie ma. Ufasz, że dostarczy javascript, to samo dotyczy JSONP. - jvenema
Warto zauważyć, że możesz nieco zwiększyć bezpieczeństwo, zmieniając sposób zwracania danych. Jeśli zwrócisz skrypt w prawdziwym formacie JSON, takim jak mycallback ('{"foo": "bar"}') (zauważ, że parametr jest teraz ciągiem znaków), możesz ręcznie sparsować dane, aby "wyczyścić" je wcześniej oceniać. - jvenema
CURL jest rozwiązaniem po stronie serwera, a nie po stronie klienta. Służą dwóm różnym celom. - jvenema


JSONP jest naprawdę prostą sztuczką do pokonania XMLHttpRequest te same zasady domeny. (Jak wiadomo, nie można wysłać AJAX (XMLHttpRequest) wniosek do innej domeny.)

Więc - zamiast używać XMLHttpRequest musimy użyć scenariusz Znaczniki HTML, zwykle używane do ładowania plików js, aby js mógł pobierać dane z innej domeny. Brzmi dziwnie?

Rzecz jest - okazuje się scenariusz tagi mogą być używane w sposób podobny do XMLHttpRequest! Sprawdź to:

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

Skończysz z scenariusz segment, który wygląda tak po załadowaniu danych:

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

Jest to jednak trochę niewygodne, ponieważ musimy pobrać tę tablicę scenariusz etykietka. Więc JSONP twórcy zdecydowali, że to zadziała lepiej (i jest):

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

Zwróć uwagę na my_callback funkcjonować tam? Więc kiedy JSONP serwer odbiera twoje żądanie i znajduje parametr wywołania zwrotnego - zamiast zwracać tablicę JS zwróci to:

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

Zobacz, gdzie jest zysk: teraz otrzymujemy automatyczne wywołanie zwrotne (my_callback), które zostanie uruchomione po otrzymaniu danych.
To wszystko, o czym trzeba wiedzieć JSONP: to znacznik wywołania zwrotnego i skryptu.

UWAGA: są to proste przykłady użycia JSONP, nie są to skrypty gotowe do użycia.

Podstawowy przykład kodu JavaScript (prosty kanał RSS z użyciem 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>

Podstawowy przykład jQuery (prosty kanał na Twitterze za pomocą 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 oznacza JSON z wyściółką. (bardzo słabo nazwana technika, ponieważ tak naprawdę nie ma nic wspólnego z tym, co większość ludzi uznałaby za "dopełnienie").


640
2017-07-29 21:40



Dzięki za wyjaśnienie tagu skryptu. Nie byłem w stanie dowiedzieć się, jak polityka bezpieczeństwa krzyżowego została ominięta przez JSONP. Po wyjaśnieniu czuję się trochę głupio, by nie zauważyć punktu ... - Eduard
Jest to bardzo dobra uzupełniająca odpowiedź na odpowiedź Jvenemy - nie rozumiem, dlaczego wywołanie zwrotne było konieczne, dopóki nie wskazałeś, że w przeciwnym razie dane JSON będą musiały być dostępne za pośrednictwem elementu skryptu. - Matt
Czuję się niesamowicie, wiedząc, że tag skryptu działa jako XMLHttp :-) Dzięki za miłe wyjaśnienie - ravisoni
Dzięki za tak klarowne wyjaśnienie. Szkoda, że ​​moje podręczniki do college'u nie zostały napisane przez takich ludzi jak ty :) - hashbrown
Dobre wyjaśnienie, a nie poprzednie. Oczywiście - twój fragment "te, których zwykle używasz do ładowania plików js, aby js mógł uzyskać dane z innej domeny. Brzmi dziwnie?" jest również dla mnie otwieraczem do oczu. Przykładowy kod w bardzo dużym stopniu. - SIslam


JSONP działa poprzez skonstruowanie elementu "script" (w znacznikach HTML lub wstawionego do DOM przez JavaScript), który wysyła żądanie do zdalnej lokalizacji usługi danych. Odpowiedzią jest javascript załadowany do przeglądarki z nazwą predefiniowanej funkcji wraz z przekazywanym parametrem, czyli żądanymi danymi JSON. Po wykonaniu skryptu wywoływana jest funkcja wraz z danymi JSON, dzięki czemu strona żądająca może odbierać i przetwarzać dane.

Do dalszej lektury Odwiedź:  https://blogs.sap.com/2013/07/15/secret-behind-jsonp/

fragment strony kodu klienta

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

Po stronie serwera fragment kodu 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 . ")";
?>

38
2018-03-17 13:32



link na górze zaledwie 404s teraz - Man Personson
Treść tego linku jest już dostępna pod adresem http://scn.sap.com/community/developer-center/front-end/blog/2013/07/15/secret-behind-jsonp. - ᴠɪɴᴄᴇɴᴛ


Ponieważ możesz poprosić serwer o dołączenie prefiksu do zwróconego obiektu JSON. Na przykład

function_prefix(json_object);

aby przeglądarka mogła eval "inline" ciąg JSON jako wyrażenie. Ta sztuczka umożliwia serwerowi "wstrzyknięcie" kodu javascript bezpośrednio w przeglądarce klienta, a to z pominięciem ograniczeń "tego samego pochodzenia".

Innymi słowy, możesz mieć międzydomenowa wymiana danych.


Normalnie XMLHttpRequest nie zezwala na bezpośrednią wymianę danych między domenami (należy przejść przez serwer w tej samej domenie), podczas gdy:

<script src="some_other_domain/some_data.js&prefix=function_prefix> `można uzyskać dostęp do danych z domeny innej niż z punktu początkowego.


Warto również zauważyć: mimo że serwer powinien być uznany za "zaufany" przed próbą tego rodzaju "sztuczki", skutki uboczne możliwej zmiany w formacie obiektu itp. Mogą być zawarte. Jeśli function_prefix(tj. właściwa funkcja js) jest wykorzystywana do odbierania obiektu JSON, wspomniana funkcja może wykonywać sprawdzenia przed zaakceptowaniem / dalszym przetwarzaniem zwróconych danych.


37
2018-01-14 20:58





JSONP jest świetnym sposobem na obejście błędów skryptów cross-domain. Możesz korzystać z usługi JSONP wyłącznie z JS bez konieczności implementowania proxy AJAX po stronie serwera.

Możesz użyć b1t.co usługa, aby zobaczyć, jak to działa. Jest to bezpłatna usługa JSONP, która pozwala zminimalizować adresy URL. Oto adres URL do korzystania z usługi:

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

Na przykład połączenie, http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

wróci

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

I tak, kiedy ten zostanie załadowany do twojego js jako src, automatycznie uruchomi dowolną Nazwę Javascript, którą powinieneś zaimplementować jako funkcję zwrotną:

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

Aby wykonać wywołanie JSONP, możesz zrobić to na kilka sposobów (w tym używając jQuery), ale tutaj jest czysty przykład JS:

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

Przykład "krok po kroku" i serwis internetowy jsonp do ćwiczenia jest dostępny pod adresem: ten post


17
2018-03-28 15:59



Dziękujemy za przesłanie odpowiedzi! Pamiętaj, że powinieneś opublikować najważniejsze części odpowiedzi tutaj, na tej stronie lub usunąć informacje o Twoim ryzyku Zobacz FAQ, gdzie wymienia odpowiedzi, które są "ledwie więcej niż link". Możesz dodać link, jeśli chcesz, ale tylko jako "referencję". Odpowiedź powinna być samodzielna bez potrzeby korzystania z linku. - Taryn♦


Prosty przykład użycia 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





Zanim zrozumiesz JSONP, musisz znać format JSON i XML. Obecnie najczęściej używanym formatem danych w Internecie jest XML, ale XML jest bardzo skomplikowany. Uniemożliwia użytkownikom przetwarzanie osadzonych na stronach internetowych.

Aby JavaScript mógł łatwo wymieniać dane, nawet jako program do przetwarzania danych, używamy sformułowania zgodnego z obiektami JavaScript i opracowaliśmy prosty format wymiany danych, którym jest JSON. JSON może być używany jako dane lub jako program JavaScript.

JSON może być bezpośrednio osadzony w JavaScript, dzięki czemu można bezpośrednio uruchomić określony program JSON, ale ze względu na ograniczenia bezpieczeństwa mechanizm Sandbox przeglądarki wyłącza wykonywanie kodu JSON w wielu domenach.

Aby JSON mógł zostać przekazany po wykonaniu, opracowaliśmy JSONP. JSONP omija ograniczenia bezpieczeństwa przeglądarki z funkcją JavaScript Callback i znacznikiem <script>.

W skrócie wyjaśnia, czym jest JSONP, jaki problem rozwiązuje (kiedy go używać).


9
2017-12-08 04:02



Zignorowałem to, ponieważ nie wierzę w stwierdzenie, że XML był najczęściej używanym formatem dat w Internecie w grudniu15. - RobbyD