40 votes

JavaScript: Comment créer du JSONP?

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 JSON ** P ** a été créé.

La question est, comment puis-je modifier mon API JSON pour le rendre compatible JSONP?

Fondamentalement, comment puis-je créer l'API de rappel?

METTRE À JOUR

Ma langue côté serveur est PHP

76voto

mauris Points 19666

C'est simple. Simplement accepter un paramètre appelé callback dans le GET.

Enrouler ensuite le rappel de la fonction JavaScript 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;
}

C'est l'idée est de simplement retourner un fichier JavaScript qui appelle la fonction de rappel avec l'objet JSON en tant que premier paramètre de le JavaScript de la fonction de rappel.

Vous pouvez utiliser le haut- json_encode() fonction pour créer des chaînes JSON (qui $data dans notre exemple ci-dessus contient) à partir de tableaux et d'objets en PHP.

Pour utiliser le JSONP service, vous pouvez utiliser l' <script> balise:

<script>
    function receiver(data){
        console.log(data);
    }
</script>
<script src="data-service.php?callback=receiver"></script>

26voto

CMS Points 315406

Vous avez besoin d'un langage côté serveur, la fonction de rappel paramètre est simplement un paramètre GET, vous lisez le param, et vous envelopper la réponse JSON dans un appel de fonction et de l'imprimer comme ce callback(jsonResponse);.

Je vous laisse un très minimaliste exemple à l'aide de Python, puisque vous ne mentionnez pas tout le 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

Qui est le code d'une petite JSONP service utilisé pour récupérer l'adresse IP du client faite par Zach et elle est hébergée sur le Google App Engine.

6voto

Joy Dutta Points 2295

Mauris vous ai déjà donné un exemple de travail. Je voudrais seulement ajouter que vous devriez vérifier si une callback param est présent et non vide, et si non, renvoyer les données json comme c'est sans les parenthèses. Donc, fondamentalement, votre api JSON avec mise à disposition de JSON-P lors de l' callback est donné.

Pour consommer le JSON-P webservice, à moins d'utiliser un framework comme YUI ou jQuery, il vous suffit de créer un script nœud de façon dynamique et définir sa src d'attribut pour pointer vers le webservice. N'oubliez pas de supprimer le nœud du dom avant de répéter de nouveau, car ce script dynamique nœud est à usage unique seulement.

4voto

jkinz Points 547

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

3voto

Dmitriy Naumov Points 2084
 // 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&param=anything', '', 'js');
 

/// le script de rappel devrait renvoyer le nom de la fonction de rappel, c'est-à-dire si vous tapez dans le navigateur

http: //url_to_receiver_script/index.php&param=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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X