Вопрос: Что такое JSONP? [Дубликат]


Я понимаю JSON, но не JSONP. Документ Википедии о JSON является (был) верхним результатом поиска для JSONP. В нем говорится следующее:

JSONP или «JSON с дополнением» - это расширение JSON, в котором префикс указан как входной аргумент самого вызова.

А? Какой звонок? Это не имеет никакого смысла для меня. JSON - это формат данных. Нет звонка.

2-й результат поиска от какого-то парня по имени Remy , который пишет об этом JSONP:

JSONP - это вставка сценария, передавая ответ от сервера в указанную пользователем функцию.

Я могу понять это, но это все еще не имеет никакого смысла.


Так что же такое JSONP? Почему он был создан (какая проблема его решает)? И зачем мне это использовать?


добавление : Я только что создал новая страница для JSONP в Википедии; теперь у него есть четкое и подробное описание JSONP, основанного на jvenema ответ.


1821


источник


Ответы:


На самом деле это не слишком сложно ...

Скажите, что вы находитесь на сайте example.com, и хотите сделать запрос на домен example.net. Для этого вам необходимо пересечь границы домена, no-no в большинстве браузеров.

Один элемент, который обходит это ограничение, - это теги <script>. Когда вы используете тег скрипта, ограничение домена игнорируется, но при нормальных обстоятельствах вы не можете делать что-либо с результатами, сценарий просто оценивается.

Введите JSONP. Когда вы делаете свой запрос на сервер, который включен JSONP, вы передаете специальный параметр, который немного сообщает серверу о вашей странице. Таким образом, сервер может красиво завершать свой ответ так, как может обрабатывать ваша страница.

Например, скажем, сервер ожидает параметр «обратный вызов», чтобы включить его возможности JSONP. Тогда ваш запрос будет выглядеть так:

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

Без JSONP это может вернуть некоторый базовый объект JavaScript, например:

{ foo: 'bar' }

Однако с JSONP, когда сервер получает параметр «обратный вызов», он немного уменьшает результат, возвращая что-то вроде этого:

mycallback({ foo: 'bar' });

Как вы можете видеть, теперь он будет вызывать указанный вами метод. Итак, на вашей странице вы определяете функцию обратного вызова:

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

И теперь, когда скрипт будет загружен, он будет оценен, и ваша функция будет выполнена. Voila, междоменные запросы!

Также стоит отметить одну серьезную проблему с JSONP: вы теряете много контроля над запросом. Например, нет «хорошего» способа вернуть коды отказа. В результате вы в конечном итоге используете таймеры для отслеживания запроса и т. Д., Что всегда немного подозрительно. Предложение для JSONRequest является отличным решением для разрешения междоменного скриптинга, обеспечения безопасности и обеспечения правильного управления запросом.

В эти дни (2015), CORS это рекомендуемый подход против JSONRequest. JSONP по-прежнему полезен для более старой поддержки браузеров, но с учетом последствий для безопасности, если у вас нет выбора, CORS - лучший выбор.


1785



JSONP на самом деле простой трюк, чтобы преодолеть XMLHttpRequest той же политики домена. (Как вы знаете, никто не может отправить AJAX (XMLHttpRequest) запрос в другой домен.)

Итак - вместо использования XMLHttpRequest мы должны использовать скрипт HTML-теги, те, которые вы обычно используете для загрузки js-файлов, чтобы js мог получать данные из другого домена. Звучит странно?

Вещь - получается скрипт теги могут использоваться в моде, подобном 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? Обратный вызов = my_callback ';

Обратите внимание на my_callback функция там? Так когда JSONP сервер получает ваш запрос и находит параметр обратного вызова - вместо возврата простого массива js он возвращает это:

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

Посмотрите, где прибыль: теперь мы получаем автоматический обратный вызов (my_callback), который будет срабатывать после получения данных.
Это все, что нужно знать о JSONP : это теги обратного вызова и сценария.

ПРИМЕЧАНИЕ. Это простые примеры использования JSONP, это не готовые сценарии производства.

Пример базового JavaScript (простой канал Twitter с использованием 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>

Основной пример jQuery (простой канал Twitter с использованием 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 означает JSON с Padding , (очень плохо названная техника, так как она действительно не имеет ничего общего с тем, что большинство людей будет считать «заполнением»).


636



JSONP работает, создавая элемент «script» (либо в разметке HTML, либо вставляемый в DOM через JavaScript), который запрашивает местоположение удаленной службы данных. Ответ - это javascript, загруженный в ваш браузер с именем предопределенной функции вместе с передаваемым параметром, который запрашивает данные JSON. Когда скрипт выполняется, функция вызывается вместе с данными 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 . ")";
?>

38



Поскольку вы можете попросить сервер добавить префикс к возвращенному объекту JSON. Например

function_prefix(json_object);

для того, чтобы браузер eval«inline» строка JSON как выражение. Этот трюк позволяет серверу «вводить» javascript-код непосредственно в браузере клиента, и это обходит ограничения «того же происхождения».

Другими словами, вы можете междоменный обмен данными ,


Как обычно, XMLHttpRequestне разрешает междоменный обмен данными напрямую (нужно пройти через сервер в том же домене), тогда как:

<script src="some_other_domain/some_data.js&prefix=function_prefix> `можно получить доступ к данным из домена, отличного от источника.


Также стоит отметить: даже несмотря на то, что сервер должен считаться «доверенным», прежде чем пытаться использовать этот «трюк», могут быть включены побочные эффекты возможных изменений в формате объекта и т. Д. Если function_prefix(т. е. надлежащая js-функция) используется для приема объекта JSON, эта функция может выполнять проверки перед принятием / дальнейшей обработкой возвращенных данных.


37



JSONP is a great away to get around cross-domain scripting errors. You can consume a JSONP service purely with JS without having to implement a AJAX proxy on the server side.

You can use the b1t.co service to see how it works. This is a free JSONP service that alllows you to minify your URLs. Here is the url to use for the service:

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

For example the call, http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

would return

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

And thus when that get's loaded in your js as a src, it will automatically run whateverJavascriptName which you should implement as your callback function:

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

To actually make the JSONP call, you can do it about several ways (including using jQuery) but here is a pure JS example:

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

A step by step example and a jsonp web service to practice on is available at: this post


17



A simple example for the usage of 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



Before understanding JSONP, you need to know JSON format and XML. Currently the most frequently used data format on the web is XML, but XML is very complicated. It makes users inconvenient to process embedded in Web pages.

To make JavaScript can easily exchange data, even as the data processing program, we use the wording according to JavaScript objects and developed a simple data exchange format, which is JSON. JSON can be used as data, or as a JavaScript program.

JSON can be directly embedded in JavaScript, using them you can directly execute certain JSON program, but due to security constraints, the browser Sandbox mechanism disables cross-domain JSON code execution.

To make JSON can be passed after the execution, we developed a JSONP. JSONP bypass the security limits of the browser with JavaScript Callback functionality and the < script > tag.

So in short it explains what JSONP is, what problem it solves (when to use it).


9