J'ai deux domaines, exemple1.com et exemple2.com
De example1.com, j'aimerais appeler une API JSON que j'ai sur example2.com. Sachant que cela n’est pas permis, j’ai eu l’impression - c’est exactement pourquoi JSONPa été créé.
La question est, comment puis-je modifier mon API JSON pour le rendre compatible JSONP?
Fondamentalement, comment créer l’API de rappel?
METTRE À JOUR
Ma langue côté serveur est PHP
C'est simple. Acceptez simplement un paramètre appelé callback
dans GET.
Enroulez ensuite la fonction JavaScript de rappel autour de vos données.
Exemple en PHP:
<?php
$data = '{}'; // json string
if(array_key_exists('callback', $_GET)){
header('Content-Type: text/javascript; charset=utf8');
header('Access-Control-Allow-Origin: http://www.example.com/');
header('Access-Control-Max-Age: 3628800');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
$callback = $_GET['callback'];
echo $callback.'('.$data.');';
}else{
// normal JSON string
header('Content-Type: application/json; charset=utf8');
echo $data;
}
L'idée est de simplement renvoyer un fichier JavaScript qui appelle la fonction de rappel avec l'objet JSON en tant que premier paramètre de la fonction de rappel JavaScript.
Vous pouvez utiliser la fonction json_encode()
intégrée pour créer des chaînes JSON (que contient $data
dans notre exemple ci-dessus) à partir de tableaux et d'objets en PHP.
Pour utiliser le service JSONP, vous pouvez utiliser la balise <script>
:
<script>
function receiver(data){
console.log(data);
}
</script>
<script src="data-service.php?callback=receiver"></script>
Vous avez besoin d'un langage côté serveur, le paramètre de rappel est simplement un paramètre GET, vous lisez le paramètre, vous enroulez la réponse JSON dans un appel de fonction et vous l'imprimez comme ceci callback(jsonResponse);
.
Je vous laisse un exemple vraiment minimaliste utilisant Python puisque vous ne mentionnez aucun langage côté serveur:
import os
import cgi
form = cgi.FieldStorage()
callback = form.getvalue('callback','')
address = cgi.escape(os.environ["REMOTE_ADDR"])
json = '{"ip": "'+address+'", "address":"'+address+'"}'
#Allow cross domain XHR
print 'Access-Control-Allow-Origin: *'
print 'Access-Control-Allow-Methods: GET'
if callback != '':
print 'Content-Type: application/javascript'
result = callback+'('+json+');'
else:
print 'Content-Type: application/json'
result = json
print ''
print result
C'est le code d'un petit service JSONP utilisé pour extraire l'adresse IP du client créée par Zach et il est hébergé sur le Google App Engine .
Mauris vous a déjà donné un exemple de travail. J'ajouterai seulement que vous devriez vérifier si un paramètre callback
est présent et non vide, et si ce n'est pas le cas, renvoyer les données json telles quelles sans les parenthèses. Donc, fondamentalement, votre api sera JSON avec la possibilité d’être JSON-P lorsque callback
est donné.
Pour utiliser le service Web JSON-P, vous pouvez créer un noeud de script de manière dynamique et définir un attribut src
de manière à pointer vers le service Web, à moins que vous n'utilisiez un cadre tel que YUI ou jQuery. N'oubliez pas de supprimer le noeud du dom avant de le répéter, car ce noeud de script dynamique est à usage unique.
Je sais que je suis en retard pour le parti, et l'une des réponses a été faite à propos de la sécurité du code. Voici un bon article à ce sujet:
http://www.geekality.net/2010/06/27/php-how-to-easily-provide-json-and-jsonp/
Et voici le code que vous devriez utiliser:
<?php header('content-type: application/json; charset=utf-8');
function is_valid_callback($subject)
{
$identifier_syntax
= '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*+$/u';
$reserved_words = array('break', 'do', 'instanceof', 'typeof', 'case',
'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue',
'for', 'switch', 'while', 'debugger', 'function', 'this', 'with',
'default', 'if', 'throw', 'delete', 'in', 'try', 'class', 'enum',
'extends', 'super', 'const', 'export', 'import', 'implements', 'let',
'private', 'public', 'yield', 'interface', 'package', 'protected',
'static', 'null', 'true', 'false');
return preg_match($identifier_syntax, $subject)
&& ! in_array(mb_strtolower($subject, 'UTF-8'), $reserved_words);
}
$data = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
$json = json_encode($data);
# JSON if no callback
if( ! isset($_GET['callback']))
exit($json);
# JSONP if valid callback
if(is_valid_callback($_GET['callback']))
exit("{$_GET['callback']}($json)");
# Otherwise, bad request
header('status: 400 Bad Request', true, 400);
// Adds script tag to head of the page
function addScriptToHead(source, code, type) {
var script = document.createElement('script');
if (type === 'js') {
script.setAttribute('type', 'text/javascript');
}
if (source !== '') {
script.setAttribute('src', source);
}
if (code !== '') {
if (document.all && !window.opera) {
script.text = code;
} else {
script.innerHTML = code;
}
}
document.getElementsByTagName('head')[0].appendChild(script);
}
// Callback function
function addScriptToHead(any_param) {
// do whatever needs to be done
}
//call example
addScriptToHead('http://url_to_receiver_script/index.php¶m=anything', '', 'js');
/// le script de rappel doit renvoyer le nom de la fonction de rappel, c'est-à-dire si vous tapez dans le navigateur
http: //url_to_receiver_script/index.php¶m=anything
il devrait renvoyer juste un texte (nom de la fonction de traitement existante): addScriptToHead (any_param)
fonctionne comme une horloge dans n'importe quel navigateur.
Facile avec jQuery, C'est le côté client:
$.ajax({
dataType: 'jsonp',
data: "somedata="+somevalue,
//this is very important since it's the callback we will and that allow cross domain
jsonp: 'jsonp_callback',
url: 'http://example2.com',
//function we trigger on success
success: ParseJson
//error handling not working with jsonP
//error: handleError
});
function ParseJson(data)
{
for (var key in data) {
if (data.hasOwnProperty(key)) {
alert(key + " -> " + data[key]);
}
}
}
Et assurez-vous d’obtenir le bon json du côté serveur;
et n'oubliez pas de renvoyer le paramètre jsonp_callback, sinon cela ne fonctionnera pas !!!!!
et c'est tout.
exemple ici __. http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html
<script src=".../example2...?output=json;callback=loadit"></script>
<script>
alert( "I got this from example2 " + loadit);
</script>
Vous pouvez utiliser le JSON simple pour PHP pour le falsifier! Cela simplifie tout!
<?php
include('../includes/json.php');
$json = new json('callback', 'myCallback');
$object = new stdClass();
$object->FirstName = 'John';
$object->LastName = 'Doe';
$array = array(1,'2', 'Pieter', true);
$jsonOnly = '{"Hello" : "darling"}';
// Add objects to send
$json->add('status', '200');
$json->add("worked");
$json->add("things", false);
$json->add('friend', $object);
$json->add("arrays", $array);
$json->add("json", $jsonOnly, false);
/*
Expected result :
myCallback({
"status": "200",
"worked": true,
"things": false,
"friend": {
"FirstName": "John",
"LastName": "Doe"
},
"arrays": [
1,
"2",
"Pieter",
true
],
"json": {
"Hello": "darling"
}
});
*/
$json->send();
?>