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?
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
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
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);
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.
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)
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/
/**
* 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');
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);
};
});
}
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);
}
}
/**
* 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' );
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.