Comment faire une requête JSONP depuis Javascript sans JQuery?

puis-je faire une requête JSONP dans JavaScript sans utiliser jQuery ou une autre bibliothèque externe? Je voudrais utiliser JavaScript lui-même et puis analyser les données et en faire un objet pour que je puisse l'utiliser. Dois-je utiliser une bibliothèque externe? Si non, comment puis-je le faire?

113
demandé sur informatik01 0000-00-00 00:00:00

11 réponses

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
147
répondu Matt Ball 2013-03-11 14:35:42

exemple léger (avec support pour onSuccess et onTimeout). Vous devez passer le nom du callback dans L'URL si vous en avez besoin.

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

exemple d'utilisation:

$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

33
répondu sobstel 2014-07-27 07:27:38

Qu'est-ce que JSONP?

la chose importante à se rappeler avec jsonp est qu'il ne s'agit pas réellement d'un protocole ou d'un type de données. C'est juste une façon de charger un script à la volée et de traiter le script qui est présenté à la page. Dans l'esprit de JSONP, cela signifie introduire un nouvel objet javascript du serveur dans l'application/ script client.

quand est JSONP - elle nécessaire?

c'est une méthode pour permettre à un domaine d'accéder/ traiter des données d'un autre dans la même page de manière asynchrone. Principalement, il est utilisé pour outrepasser les restrictions CORS (Cross Origin Resource Sharing) qui se produiraient avec une requête XHR (ajax). Les chargements de scripts ne sont pas soumis aux restrictions de la CORS.

Comment faire

Introduction d'un nouvel objet javascript à partir du serveur peut être implémenté de nombreuses façons, mais la pratique la plus courante est que le serveur implémente l'exécution d'une fonction de 'callback', avec l'objet requis passé dedans. La fonction de rappel est juste une fonction que vous avez déjà configuré sur le client le script vous chargez appels au point le script charges à traiter les données transmises.

exemple:

I avoir une application qui enregistre tous les éléments dans la maison de quelqu'un. Mon application est prête et je veux maintenant récupérer tous les articles de la chambre principale.

ma demande est sur app.home.com . Les API à partir desquelles je dois charger les données sont sur api.home.com .

à moins que le serveur ne soit explicitement configuré pour l'autoriser, Je ne peux pas utiliser ajax pour charger ces données, car même les pages sur des sous-domaines distincts sont soumises à des restrictions XHR CORS.

idéalement, configurer les choses pour permettre x-domain XHR

Idéalement, puisque l'api et l'application sont sur le même domaine, je pourrais avoir accès à définir les en-têtes sur api.home.com . Si je le fais, je peux ajouter un en-tête Access-Control-Allow-Origin: donnant accès à app.home.com . En supposant que l'en-tête est configuré comme suit: Access-Control-Allow-Origin: "http://app.home.com" , c'est beaucoup plus sûr que de configurer JSONP. C'est parce que app.home.com peut obtenir tout ce qu'il veut de api.home.com sans api.home.com donnant à CORS accès à l'ensemble de l'internet.

la solution XHR ci-dessus n'est pas possible. Configurer JSONP sur mon script client: j'ai configuré une fonction pour traiter la réponse du serveur lorsque je fais l'appel JSONP . :

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

le serveur devra être configuré pour renvoyer un mini script ressemblant à "processJSONPResponse({"room":"main bedroom","items":["bed","chest of drawers"]});" il pourrait être conçu pour renvoyer une telle chaîne si quelque chose comme //api.home.com?getdata=room&room=main_bedroom s'appelle.

puis le client configure une étiquette de script comme telle:

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

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

charge le script et appelle immédiatement window.processJSONPResponse() comme écrit/ echo/ imprimé par le serveur. Les données transmises comme paramètre à la fonction sont maintenant stockées dans la variable locale dataFromServer et vous pouvez en faire tout ce dont vous avez besoin.

Nettoyage

une Fois que le client a les données, c'est à dire. immédiatement après l'ajout du script au DOM, l'élément script peut être supprimé du DOM:

script.parentNode.removeChild(script);
25
répondu dewd 2015-02-01 18:31:17

ma compréhension est que vous utilisez réellement des balises script avec JSONP, sooo...

la première étape est de créer votre fonction qui gérera le JSON:

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

s'assurer que cette fonction est accessible au niveau global.

ensuite, ajouter un élément script au DOM:

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

le script chargera le JavaScript que le fournisseur D'API construit et l'exécutera.

17
répondu sdleihssirhc 2011-05-26 01:37:05

la façon dont j'utilise jsonp comme ci-dessous:

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

alors utilisez la méthode "jsonp" comme ceci:

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

référence:

JavaScript XMLHttpRequest using JsonP

http://www.w3ctech.com/topic/721 (parler de la façon d'utiliser Promesse)

8
répondu derek 2018-07-12 20:50:21

j'ai une bibliothèque javascript pure pour faire que https://github.com/robertodecurnex/J50Npi/blob/master/J50Npi.js

regardez-le et dites-moi si vous avez besoin d'aide pour utiliser ou comprendre le code.

Btw, vous avez un exemple d'usage simple ici: http://robertodecurnex.github.com/J50Npi/

6
répondu robertodecurnex 2011-05-27 14:07:59
/**
 * 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);
  });
})();

exemple d'utilisation:

const data = await load('http://api.github.com/orgs/kriasoft');
5
répondu Konstantin Tarkus 2015-06-29 20:17:20

j'ai écrit une bibliothèque pour gérer cela, aussi simplement que possible. Pas besoin d'en externe, c'est juste une fonction. Contrairement à d'autres options, ce script nettoie après lui-même, et est généralisé pour faire d'autres requêtes à l'exécution.

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);
                };
        });
}
2
répondu Fresheyeball 2016-03-12 22:07:55

s'il vous plaît trouver ci-dessous JavaScript exemple pour faire un JSONP appel sans JQuery:

aussi, vous pouvez me référer à mon dépôt GitHub pour référence.

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);
    }
}
1
répondu Mayur Shedage 2018-07-27 05:19:30
/**
 * 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' );
0
répondu Chris Ferdinandi 2015-06-26 15:43:01

si vous utilisez ES6 avec NPM, vous pouvez essayer le module node"fetch-jsonp". Fetch API fournit le support pour faire un appel JsonP comme un appel XHR régulier.

condition préalable: vous devriez utiliser le module de noeud isomorphic-fetch dans votre pile.

0
répondu Rajendra kumar Vankadari 2018-03-19 06:12:59