Подтвердить что ты не робот

Как сделать запрос JSONP из Javascript без JQuery?

Могу ли я сделать запрос JSONP междоменного доступа в JavaScript без использования jQuery или другой внешней библиотеки? Я хотел бы использовать сам JavaScript, а затем проанализировать данные и сделать его объектом, чтобы я мог его использовать. Нужно ли использовать внешнюю библиотеку? Если нет, как я могу это сделать?

4b9b3361

Ответ 1

function foo(data)
{
    // do stuff with JSON
}

var script = document.createElement('script');
script.src = '//example.com/path/to/jsonp?callback=foo'

document.getElementsByTagName('head')[0].appendChild(script);
// or document.head.appendChild(script) in modern browsers

Ответ 2

Легкий пример (с поддержкой onSuccess и onTimeout). Вам нужно передать имя обратного вызова в URL, если вам это нужно.

var $jsonp = (function(){
  var that = {};

  that.send = function(src, options) {
    var callback_name = options.callbackName || 'callback',
      on_success = options.onSuccess || function(){},
      on_timeout = options.onTimeout || function(){},
      timeout = options.timeout || 10; // sec

    var timeout_trigger = window.setTimeout(function(){
      window[callback_name] = function(){};
      on_timeout();
    }, timeout * 1000);

    window[callback_name] = function(data){
      window.clearTimeout(timeout_trigger);
      on_success(data);
    }

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.src = src;

    document.getElementsByTagName('head')[0].appendChild(script);
  }

  return that;
})();

Использование образца:

$jsonp.send('some_url?callback=handleStuff', {
    callbackName: 'handleStuff',
    onSuccess: function(json){
        console.log('success!', json);
    },
    onTimeout: function(){
        console.log('timeout!');
    },
    timeout: 5
});

В GitHub: https://github.com/sobstel/jsonp.js/blob/master/jsonp.js

Ответ 3

Что такое JSONP?

Важная вещь, которую нужно запомнить с помощью jsonp, заключается в том, что на самом деле это не протокол или тип данных. Это всего лишь способ загрузки script на лету и обработки script, который вводится на страницу. В духе JSONP это означает введение нового объекта javascript с сервера в клиентское приложение /script.

Когда нужен JSONP?

Это один из способов разрешить одному домену получать или обрабатывать данные из другого на одной странице асинхронно. Прежде всего, он используется для переопределения ограничений CORS (Cross Origin Resource Sharing), которые могут возникнуть с запросом XHR (ajax). script нагрузки не подпадают под ограничения CORS.

Как это сделать

Введение нового объекта javascript с сервера может быть реализовано многими способами, но наиболее распространенной практикой является то, что сервер реализует выполнение функции "обратного вызова" с переданным им обязательным объектом. Функция обратного вызова - это только функция, которую вы уже настроили на клиенте, который script загружает вызовы в точке загрузки script для обработки данных, переданных ей.

Пример:

У меня есть приложение, которое регистрирует все элементы в доме. Мое приложение настроено, и теперь я хочу получить все предметы в главной спальне.

Мое приложение находится на app.home.com. Мне нужно загрузить данные из apis на api.home.com.

Если сервер явно не настроен для его разрешения, я не могу использовать ajax для загрузки этих данных, так как даже страницы на отдельных субдоменах могут быть ограничены XHR CORS.

В идеале установите все, чтобы разрешить X-домен XHR

В идеале, поскольку api и app находятся в одном домене, у меня может быть доступ к настройке заголовков на api.home.com. Если да, я могу добавить элемент заголовка Access-Control-Allow-Origin:, предоставляющий доступ к app.home.com. Предполагая, что заголовок настроен следующим образом: Access-Control-Allow-Origin: "http://app.home.com", это гораздо безопаснее, чем настройка JSONP. Это связано с тем, что app.home.com может получить все, что хочет от api.home.com без api.home.com, предоставляя CORS доступ ко всему интернету.

Вышеупомянутое решение XHR невозможно. Настройка JSONP На моем клиенте script: Я настроил функцию для обработки ответа с сервера при вызове JSONP.:

function processJSONPResponse(data) {
    var dataFromServer = data;
}

Необходимо настроить сервер, чтобы вернуть mini script, выглядящий как-то вроде "processJSONPResponse({"room":"main bedroom","items":["bed","chest of drawers"]});". Он может быть создан для возврата такой строки, если вызывается что-то вроде //api.home.com?getdata=room&room=main_bedroom.

Затем клиент устанавливает тег script как таковой:

var script = document.createElement('script');
script.src = '//api.home.com?getdata=room&room=main_bedroom';

document.querySelector('head').appendChild(script);

Загружает script и сразу вызывает window.processJSONPResponse() как написанный/эхо/распечатанный сервером. Данные, переданные в качестве параметра функции, теперь сохраняются в локальной переменной dataFromServer, и вы можете делать с ней все, что вам нужно.

Очистка

Как только клиент имеет данные, т.е. сразу после добавления script в DOM элемент script может быть удален из DOM:

script.parentNode.removeChild(script);

Ответ 4

Я понимаю, что вы действительно используете теги script с JSONP, sooo...

Первым шагом будет создание вашей функции, которая будет обрабатывать JSON:

function hooray(json) {
    // dealin wit teh jsonz
}

Убедитесь, что эта функция доступна на глобальном уровне.

Затем добавьте элемент script в DOM:

var script = document.createElement('script');
script.src = 'http://domain.com/?function=hooray';
document.body.appendChild(script);

script загрузит JavaScript, созданный поставщиком API, и выполнит его.

Ответ 5

как я использую JSONP, как показано ниже:

function jsonp(uri) {
    return new Promise(function(resolve, reject) {
        var id = '_' + Math.round(10000 * Math.random());
        var callbackName = 'jsonp_callback_' + id;
        window[callbackName] = function(data) {
            delete window[callbackName];
            var ele = document.getElementById(id);
            ele.parentNode.removeChild(ele);
            resolve(data);
        }

        var src = uri + '&callback=' + callbackName;
        var script = document.createElement('script');
        script.src = src;
        script.id = id;
        script.addEventListener('error', reject);
        (document.getElementsByTagName('head')[0] || document.body || document.documentElement).appendChild(script)
    });
}

затем используйте метод "jsonp" следующим образом:

jsonp('http://xxx/cors').then(function(data){
    console.log(data);
});

ссылка:

JavaScript XMLHttpRequest с использованием JsonP

http://www.w3ctech.com/topic/721 (поговорим о способе использования Promise)

Ответ 6

У меня есть чистая библиотека javascript, чтобы сделать это https://github.com/robertodecurnex/J50Npi/blob/master/J50Npi.js

Взгляните на него и сообщите мне, нужна ли вам какая-либо помощь при использовании или понимании кода.

Кстати, у вас есть простой пример использования здесь: http://robertodecurnex.github.com/J50Npi/

Ответ 7

/**
 * Loads data asynchronously via JSONP.
 */
const load = (() => {
  let index = 0;
  const timeout = 5000;

  return url => new Promise((resolve, reject) => {
    const callback = '__callback' + index++;
    const timeoutID = window.setTimeout(() => {
      reject(new Error('Request timeout.'));
    }, timeout);

    window[callback] = response => {
      window.clearTimeout(timeoutID);
      resolve(response.data);
    };

    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.src = url + (url.indexOf('?') === -1 ? '?' : '&') + 'callback=' + callback;
    document.getElementsByTagName('head')[0].appendChild(script);
  });
})();

Пример использования:

const data = await load('http://api.github.com/orgs/kriasoft');

Ответ 8

Я написал библиотеку, чтобы справиться с этим, как можно проще. Не нужно делать его внешним, его только одна функция. В отличие от некоторых других опций, этот script очищает после себя и обобщается для выполнения дальнейших запросов во время выполнения.

https://github.com/Fresheyeball/micro-jsonp

function jsonp(url, key, callback) {

    var appendParam = function(url, key, param){
            return url
                + (url.indexOf("?") > 0 ? "&" : "?")
                + key + "=" + param;
        },

        createScript = function(url, callback){
            var doc = document,
                head = doc.head,
                script = doc.createElement("script");

            script
            .setAttribute("src", url);

            head
            .appendChild(script);

            callback(function(){
                setTimeout(function(){
                    head
                    .removeChild(script);
                }, 0);
            });
        },

        q =
            "q" + Math.round(Math.random() * Date.now());

    createScript(
        appendParam(url, key, q), function(remove){
            window[q] =
                function(json){
                    window[q] = undefined;
                    remove();
                    callback(json);
                };
        });
}

Ответ 9

Ниже приведен пример JavaScript для выполнения вызова JSONP без JQuery:

Кроме того, вы можете сослаться на мой репозиторий GitHub для справки.

https://github.com/shedagemayur/JavaScriptCode/tree/master/jsonp

window.onload = function(){
    var callbackMethod = 'callback_' + new Date().getTime();

    var script = document.createElement('script');
    script.src = 'https://jsonplaceholder.typicode.com/users/1?callback='+callbackMethod;

    document.body.appendChild(script);

    window[callbackMethod] = function(data){
        delete window[callbackMethod];
        document.body.removeChild(script);
        console.log(data);
    }
}

Ответ 10

/**
 * Get JSONP data for cross-domain AJAX requests
 * @private
 * @link http://cameronspear.com/blog/exactly-what-is-jsonp/
 * @param  {String} url      The URL of the JSON request
 * @param  {String} callback The name of the callback to run on load
 */
var loadJSONP = function ( url, callback ) {

    // Create script with url and callback (if specified)
    var ref = window.document.getElementsByTagName( 'script' )[ 0 ];
    var script = window.document.createElement( 'script' );
    script.src = url + (url.indexOf( '?' ) + 1 ? '&' : '?') + 'callback=' + callback;

    // Insert script tag into the DOM (append to <head>)
    ref.parentNode.insertBefore( script, ref );

    // After the script is loaded (and executed), remove it
    script.onload = function () {
        this.remove();
    };

};

/** 
 * Example
 */

// Function to run on success
var logAPI = function ( data ) {
    console.log( data );
}

// Run request
loadJSONP( 'http://api.petfinder.com/shelter.getPets?format=json&key=12345&shelter=AA11', 'logAPI' );

Ответ 11

Если вы используете ES6 с NPM, вы можете попробовать модуль узла "fetch-jsonp". Fetch API Предоставляет поддержку для выполнения вызова JsonP как обычного вызова XHR.

Предварительное условие: вы должны использовать в своем стеке модуль узла isomorphic-fetch.

Ответ 12

Просто вставив в ES6 версию собстеля, хороший ответ:

send(someUrl + 'error?d=' + encodeURI(JSON.stringify(json)) + '&callback=c', 'c', 5)
    .then((json) => console.log(json))
    .catch((err) => console.log(err))

function send(url, callback, timeout) {
    return new Promise((resolve, reject) => {
        let script = document.createElement('script')
        let timeout_trigger = window.setTimeout(() => {
            window[callback] = () => {}
            script.parentNode.removeChild(script)
            reject('No response')
        }, timeout * 1000)

        window[callback] = (data) => {
            window.clearTimeout(timeout_trigger)
            script.parentNode.removeChild(script)
            resolve(data)
        }

        script.type = 'text/javascript'
        script.async = true
        script.src = url

        document.getElementsByTagName('head')[0].appendChild(script)
    })
}