如何创建JSONP?

时间:2021-01-03 01:28:17

I have a two domains, example1.com and example2.com

我有两个域名,example1.com和example2.com

From example1.com, I would like call a JSON API I have on example2.com. Knowing that this is not allowed, it occurred to me - this is exactly why JSONP was created.

在example1.com中,我想调用example2.com上的JSON API。知道这是不允许的,我想到了——这正是JSONP创建的原因。

Question is, how do I modify my JSON API to make it JSONP capable?

问题是,如何修改JSON API以使其具备JSONP功能?

Basically, how do I create the callback api?

基本上,我如何创建回调api?

UPDATE

更新

My server side language is PHP

我的服务器端语言是PHP

8 个解决方案

#1


75  

It is simple. Simply accept a parameter called callback in the GET.

它是简单的。只需接受GET中名为callback的参数。

Then wrap the callback JavaScript function around your data.

然后围绕数据包装回调JavaScript函数。

Example in PHP:

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

It's idea is to simply return a JavaScript file which calls the callback function with the JSON object as the first parameter of the JavaScript callback function.

它的想法是返回一个JavaScript文件,该文件调用回调函数,JSON对象作为JavaScript回调函数的第一个参数。

You can use the built-in json_encode() function to create JSON strings (which $data in our example above contains) from arrays and objects in PHP.

可以使用内置的json_encode()函数在PHP中的数组和对象中创建JSON字符串(在我们的示例中包含$data)。

To use the JSONP service, you can use the <script> tag:

要使用JSONP服务,您可以使用

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

#2


26  

You need a server-side language, the callback parameter is simply a GET parameter, you read the param, and you wrap the JSON response into a function call and you print it like this callback(jsonResponse);.

您需要一种服务器端语言,回调参数只是一个GET参数,您读取param,并将JSON响应打包到函数调用中,然后像这样打印回调(jsonResponse);

I leave you a really minimalist example using Python since you don't mention any server-side language:

我留给您一个使用Python的极简示例,因为您没有提到任何服务器端语言:

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

That is the code of a small JSONP service used to retrieve the client IP address made by Zach and it is hosted on the Google App Engine.

这是一个小型JSONP服务的代码,用于检索Zach生成的客户端IP地址,它驻留在谷歌应用程序引擎上。

#3


6  

Mauris already gave you a working example. I would only add that you should check if a callback param is present and non-empty, and if not, return the json data as is without the parentheses. So basically your api will be JSON with provision of being JSON-P when callback is given.

Mauris已经给了你一个工作的例子。我只添加您应该检查一个回调param是否存在和非空,如果没有,返回json数据,就像没有括号一样。因此,在给定回调时,您的api基本上是JSON,提供的是JSON- p。

To consume the JSON-P webservice, unless you use a framework like YUI or jQuery, you can simply create a script node dynamically and set its src attribute to point to the webservice. Remember to remove the node from the dom before repeating it again, since this dynamic script node is single use only.

要使用JSON-P web服务,除非使用YUI或jQuery这样的框架,您可以动态创建一个脚本节点,并将其src属性设置为指向web服务。请记住,在重复此节点之前从dom中删除该节点,因为此动态脚本节点仅用于一次。

#4


4  

I know I'm late to the party, and there was a comment about security of the code in one of the answers. Here is a good article about this:

我知道我迟到了,在其中一个答案里有关于代码安全性的评论。这里有一篇关于这方面的好文章:

http://www.geekality.net/2010/06/27/php-how-to-easily-provide-json-and-jsonp/

http://www.geekality.net/2010/06/27/php-how-to-easily-provide-json-and-jsonp/

And here is the code that you should be running:

这是你应该运行的代码:

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

#5


3  

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

/// the callback script should return name of the Callback function, i.e. if you type in browser

//回调脚本应该返回回调函数的名称,例如,如果您在浏览器中输入

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

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

it should return just a text (name of existing processing function): addScriptToHead(any_param)

它应该只返回一个文本(现有处理函数的名称):addScriptToHead(any_param)

works like a clock in any browser.

在任何浏览器中都像时钟一样工作。

#6


2  

Easy with jQuery, that is the client side:

轻松使用jQuery,客户端:

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

And be sure that you get proper json from the server side;
and don't forget to return the jsonp_callback param, otherwise it won't work!!!!!
and that's it really.

确保从服务器端得到了适当的json;不要忘记返回jsonp_callback参数,否则它就不能工作!这是真的。

#7


0  

example here http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html basically

例子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>

#8


0  

You can use the Simple JSON for PHP to forge it! It simplify everything!

您可以使用简单的JSON来创建PHP !简化一切!

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

#1


75  

It is simple. Simply accept a parameter called callback in the GET.

它是简单的。只需接受GET中名为callback的参数。

Then wrap the callback JavaScript function around your data.

然后围绕数据包装回调JavaScript函数。

Example in PHP:

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

It's idea is to simply return a JavaScript file which calls the callback function with the JSON object as the first parameter of the JavaScript callback function.

它的想法是返回一个JavaScript文件,该文件调用回调函数,JSON对象作为JavaScript回调函数的第一个参数。

You can use the built-in json_encode() function to create JSON strings (which $data in our example above contains) from arrays and objects in PHP.

可以使用内置的json_encode()函数在PHP中的数组和对象中创建JSON字符串(在我们的示例中包含$data)。

To use the JSONP service, you can use the <script> tag:

要使用JSONP服务,您可以使用

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

#2


26  

You need a server-side language, the callback parameter is simply a GET parameter, you read the param, and you wrap the JSON response into a function call and you print it like this callback(jsonResponse);.

您需要一种服务器端语言,回调参数只是一个GET参数,您读取param,并将JSON响应打包到函数调用中,然后像这样打印回调(jsonResponse);

I leave you a really minimalist example using Python since you don't mention any server-side language:

我留给您一个使用Python的极简示例,因为您没有提到任何服务器端语言:

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

That is the code of a small JSONP service used to retrieve the client IP address made by Zach and it is hosted on the Google App Engine.

这是一个小型JSONP服务的代码,用于检索Zach生成的客户端IP地址,它驻留在谷歌应用程序引擎上。

#3


6  

Mauris already gave you a working example. I would only add that you should check if a callback param is present and non-empty, and if not, return the json data as is without the parentheses. So basically your api will be JSON with provision of being JSON-P when callback is given.

Mauris已经给了你一个工作的例子。我只添加您应该检查一个回调param是否存在和非空,如果没有,返回json数据,就像没有括号一样。因此,在给定回调时,您的api基本上是JSON,提供的是JSON- p。

To consume the JSON-P webservice, unless you use a framework like YUI or jQuery, you can simply create a script node dynamically and set its src attribute to point to the webservice. Remember to remove the node from the dom before repeating it again, since this dynamic script node is single use only.

要使用JSON-P web服务,除非使用YUI或jQuery这样的框架,您可以动态创建一个脚本节点,并将其src属性设置为指向web服务。请记住,在重复此节点之前从dom中删除该节点,因为此动态脚本节点仅用于一次。

#4


4  

I know I'm late to the party, and there was a comment about security of the code in one of the answers. Here is a good article about this:

我知道我迟到了,在其中一个答案里有关于代码安全性的评论。这里有一篇关于这方面的好文章:

http://www.geekality.net/2010/06/27/php-how-to-easily-provide-json-and-jsonp/

http://www.geekality.net/2010/06/27/php-how-to-easily-provide-json-and-jsonp/

And here is the code that you should be running:

这是你应该运行的代码:

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

#5


3  

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

/// the callback script should return name of the Callback function, i.e. if you type in browser

//回调脚本应该返回回调函数的名称,例如,如果您在浏览器中输入

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

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

it should return just a text (name of existing processing function): addScriptToHead(any_param)

它应该只返回一个文本(现有处理函数的名称):addScriptToHead(any_param)

works like a clock in any browser.

在任何浏览器中都像时钟一样工作。

#6


2  

Easy with jQuery, that is the client side:

轻松使用jQuery,客户端:

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

And be sure that you get proper json from the server side;
and don't forget to return the jsonp_callback param, otherwise it won't work!!!!!
and that's it really.

确保从服务器端得到了适当的json;不要忘记返回jsonp_callback参数,否则它就不能工作!这是真的。

#7


0  

example here http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html basically

例子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>

#8


0  

You can use the Simple JSON for PHP to forge it! It simplify everything!

您可以使用简单的JSON来创建PHP !简化一切!

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