Na czym polega JSONP?

Rozumiem JSON, ale nie JSONP. Dokument Wikipedii na temat JSON jest (był) najlepszym wynikiem wyszukiwania dla JSONP. Mówi tak:

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

Huh? Jaki telefon? To nie ma dla mnie sensu. JSON jest formatem danych. Nie ma telefonu.

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

JSONP jest iniekcją znaczników skryptowych, przekazującą odpowiedź z serwera do określonej przez użytkownika funkcji.

Mogę to zrozumieć, ale to nadal nie ma sensu.


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


Dodatek : właśnie stworzyłem nową stronę dla JSONP Na Wikipedii; teraz ma jasny i dokładny opis JSONP, oparty na jvenema 's answer.

Author: hippietrail, 2010-01-14

7 answers

To nie jest zbyt skomplikowane...

Powiedz, że jesteś na domenie example.com, i chcesz złożyć wniosek do domeny example.net. aby to zrobić, musisz przekroczyć granice domen, a Nie-Nie w większości przeglądarek.

Jedynym elementem, który omija to ograniczenie, jest

Enter JSONP. Kiedy składasz żądanie na serwer, który jest włączony JSONP, przekazujesz specjalny parametr, który mówi serwerowi trochę o twojej stronie. W ten sposób serwer jest w stanie ładnie zawinąć swoją odpowiedź w sposób, który może obsłużyć Twoja strona.

Na przykład serwer oczekuje parametru o nazwie "callback", aby włączyć jego możliwości JSONP. Wtedy twoja prośba wyglądałaby następująco:

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

Bez JSONP, może to zwrócić jakiś podstawowy obiekt JavaScript, jak więc:

{ foo: 'bar' }

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

mycallback({ foo: 'bar' });

Jak widzisz, wywoła teraz metodę, którą podałeś. Tak więc na swojej stronie definiujesz funkcję wywołania zwrotnego:

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

A teraz, kiedy skrypt zostanie załadowany, zostanie on oceniony, a twoja funkcja zostanie wykonana. Voila, zapytania między domenami!

Warto również zwrócić uwagę na jeden poważny problem z JSONP: tracisz dużą kontrolę nad żądaniem. Na przykład nie ma "ładnego" sposobu na odzyskanie odpowiednich kodów awarii. W rezultacie korzystasz z timerów do monitorowania żądania itp., co zawsze jest nieco podejrzane. Propozycja dla JSONRequest jest świetnym rozwiązaniem pozwalającym na tworzenie skryptów między domenami, zachowanie bezpieczeństwa i właściwą kontrolę żądania.

Te dni (2015), CORS jest zalecane podejście vs. JSONRequest. JSONP wciąż jest przydatne dla starszych przeglądarek, ale biorąc pod uwagę konsekwencje dla bezpieczeństwa, chyba że nie masz wyboru CORS jest lepszym wyborem.

 1826
Author: jvenema,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 00:07:18

JSONP jest naprawdę prostą sztuczką, aby przezwyciężyć XMLHttpRequest samą politykę domenową. (Jak wiadomo nie można wysłać żądania AJAX (XMLHttpRequest) do innej domeny.)

Tak więc-zamiast używać XMLHttpRequestmusimy użyć script znaczników HTML, których zwykle używamy do ładowania plików js, aby js pobierał dane z innej domeny. Brzmi dziwnie?

Rzecz w tym-okazuje się skrypt znaczniki mogą być używane w sposób podobny do XMLHttpRequest ! Zobacz też:

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

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

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

Jest to jednak nieco niewygodne, ponieważ musimy pobrać tę tablicę zscript tag. Więc JSONP twórcy zdecydowali, że to będzie działać lepiej (i tak jest):

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

Zauważ funkcję my_callback tam? Więc - kiedy serwer JSONP otrzyma Twoją prośbę i znajdzie callback parametr-zamiast zwracać zwykłą 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, co trzeba wiedzieć o JSONP : to wywołanie zwrotne i znaczniki skryptu.

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

Podstawowy przykład JavaScript (prosty kanał Twitter za pomocą 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 (simple Twitter feed using 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 uważałaby za"wyściółkę".)

 650
Author: ThatGuy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-15 07:57:19

JSONP działa poprzez konstruowanie elementu "script" (w znacznikach HTML lub wstawionego do DOM przez JavaScript), który żąda do zdalnej lokalizacji usługi danych. Odpowiedź jest javascript załadowany do przeglądarki z nazwą wstępnie zdefiniowanej funkcji wraz z przekazywanym parametrem, który jest THT dane JSON są wymagane. Gdy skrypt jest wykonywany, funkcja jest wywoływana wraz z danymi JSON, umożliwiając stronie żądającej odbiór i przetwarzanie danych.

Na Dalsze Wizyta czytelnicza: https://blogs.sap.com/2013/07/15/secret-behind-jsonp/

Fragment kodu po stronie 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 . ")";
?>
 41
Author: Ajain Vivek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-22 14:20:30

Ponieważ możesz poprosić serwer o dodanie prefiksu do zwracanego obiektu JSON. E. g

function_prefix(json_object);

W celu, aby przeglądarka eval "inline" łańcuch 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ć cross-domain data exchange.


Normalnie, XMLHttpRequest nie pozwala na cross-domeny wymiana danych bezpośrednio (trzeba przejść przez serwer w tej samej domenie) natomiast:

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


Warto również zauważyć: chociaż serwer powinien być uważany za" zaufany "przed podjęciem tego rodzaju "triku", skutki uboczne ewentualnej zmiany formatu obiektu itp. może być opanowany. Jeśli function_prefix (tj. Właściwa funkcja js) jest używana do odbioru obiektu JSON, ta funkcja może wykonywać kontrole przed zaakceptowaniem/dalszym przetwarzaniem zwracanych danych.

 37
Author: jldupont,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-13 09:22:49

JSONP to świetny sposób na obejście błędów skryptów między domenami. Możesz korzystać z usługi JSONP wyłącznie z JS bez konieczności implementacji Ajax proxy po stronie serwera.

Możesz użyć b1t.co serwis, aby zobaczyć, jak to działa. Jest to bezpłatna usługa JSONP, która pozwala na minifikację adresów URL. Oto adres URL do wykorzystania w usłudze:

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

Dla przykład wywołania, http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

Zwróci

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

I tak, gdy get zostanie załadowany do twojego js jako src, automatycznie uruchomi whateverJavascriptName, który powinieneś zaimplementować jako funkcję callback:

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

Aby wywołać JSONP, możesz to zrobić na kilka sposobów (w tym używając jQuery), ale oto 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);
}

Krok po kroku przykład i usługa internetowa jsonp do ćwiczeń jest dostępna pod adresem: ten post

 17
Author: dardawk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-05 15:20:37

Prosty przykład użycia JSONP.

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

Serwer.php

  <?php

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

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

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

    ?>    
 10
Author: sarath joseph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-06 06:45:37

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. To sprawia, że użytkownicy niewygodne do przetwarzania osadzone na stronach internetowych.

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

JSON może być bezpośrednio osadzony w JavaScript, za ich pomocą można bezpośrednio wykonać określony program JSON, ale ze względu na ograniczenia bezpieczeństwa, Mechanizm piaskownicy przeglądarki wyłącza wykonywanie kodu JSON między domenami.

Aby JSON mógł być przekazywany po wykonaniu, stworzyliśmy JSONP. JSONP omija limity bezpieczeństwa przeglądarki za pomocą funkcji zwrotnej JavaScript i tagu .

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

 9
Author: Marcus Thornton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-08 04:02:30