wake-up-neo.net

JavaScript: Wie erstelle ich JSONP?

Ich habe zwei Domains, example1.com und example2.com

Ich möchte von example1.com eine JSON-API aufrufen, die ich auf example2.com habe. Zu wissen, dass dies nicht erlaubt ist, fiel mir ein - deshalb wurde JSONPerstellt.

Die Frage ist, wie kann ich meine JSON-API so ändern, dass sie JSONP-fähig ist?

Wie erstelle ich die Callback-API?

UPDATE

Meine serverseitige Sprache ist PHP

40
Teddi

Es ist einfach. Akzeptieren Sie einfach einen Parameter namens callback im GET.

Wickeln Sie dann die Callback-JavaScript-Funktion um Ihre Daten.

Beispiel in 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;
}

Die Idee ist, einfach eine JavaScript-Datei zurückzugeben, die die Callback-Funktion mit dem JSON-Objekt als ersten Parameter der JavaScript-Callback-Funktion aufruft.

Sie können die integrierte Funktion json_encode() verwenden, um JSON-Strings (die $data in unserem Beispiel oben enthält) aus Arrays und Objekten in PHP zu erstellen. 

Um den JSONP-Dienst zu verwenden, können Sie das <script>-Tag verwenden:

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

Sie benötigen eine serverseitige Sprache, der Callback-Parameter ist lediglich ein GET-Parameter, Sie lesen den Parameter, und Sie wickeln die JSON-Antwort in einen Funktionsaufruf ein, und drucken Sie ihn wie folgt aus: callback(jsonResponse);.

Ich gebe Ihnen ein wirklich minimalistisches Beispiel für die Verwendung von Python, da Sie keine serverseitige Sprache erwähnen:

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

Dies ist der Code eines kleinen JSONP-Dienstes , der zum Abrufen der Client-IP-Adresse von Zach verwendet wird, und diese wird auf der Google App Engine gehostet.

26
CMS

Mauris hat Ihnen bereits ein Arbeitsbeispiel gegeben. Ich würde nur hinzufügen, dass Sie prüfen sollten, ob ein callback-Parameter vorhanden und nicht leer ist, und wenn nicht, geben Sie die Json-Daten ohne Klammern zurück. Im Grunde wird Ihre API also JSON sein, vorausgesetzt, dass JSON-P ist, wenn callback angegeben ist.

Wenn Sie den JSON-P-Webservice verwenden möchten, können Sie, wenn Sie kein Framework wie YUI oder jQuery verwenden, einfach einen Skriptknoten dynamisch erstellen und dessen src-Attribut auf den Webservice verweisen. Denken Sie daran, den Knoten aus dem Dom zu entfernen, bevor Sie ihn erneut wiederholen, da dieser dynamische Skriptknoten nur einmal verwendet wird.

6
Joy Dutta

Ich weiß, dass ich zu spät zur Party komme, und in einer der Antworten wurde ein Kommentar zur Sicherheit des Codes angegeben. Hier ist ein guter Artikel dazu: 

http://www.geekality.net/2010/06/27/php-wie-nach-einfach-genehmigt-json-und-jsonp/

Und hier ist der Code, den Sie ausführen sollten: 

<?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);
4
jkinz
// 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');

/// Das Callback-Skript sollte den Namen der Callback-Funktion zurückgeben, d. h. wenn Sie im Browser eingeben

http: //url_to_receiver_script/index.php&param=anything

es sollte nur ein Text (Name der vorhandenen Verarbeitungsfunktion) zurückgegeben werden: addScriptToHead (any_param)

funktioniert in jedem Browser wie eine Uhr.

3
Dmitriy Naumov

Einfach mit jQuery.... Das ist die Client-Seite:

  $.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]);
  }
}
}

Stellen Sie sicher, dass Sie auf der Serverseite den richtigen Json erhalten. 
und vergessen Sie nicht, den Parameter jsonp_callback zurückzugeben, sonst funktioniert es nicht !!!!!
und das ist es wirklich.

2
Tom

beispiel hier http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html grundsätzlich

<script src=".../example2...?output=json;callback=loadit"></script>
<script>
alert( "I got this from example2 " + loadit);
</script>
0
asdf

Sie können das Simple JSON für PHP verwenden, um es zu fälschen! Es vereinfacht alles!

<?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();
?>
0
Alexis Paques