JavaScript:如何创建 JSONP?

发布于 2024-08-10 06:40:28 字数 252 浏览 4 评论 0原文

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

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

问题是,如何修改 JSON API 以使其支持 JSONP?

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

更新

我的服务器端语言是 PHP

I have a two domains, example1.com and 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.

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

Basically, how do I create the callback api?

UPDATE

My server side language is PHP

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

_蜘蛛 2024-08-17 06:40:28

这很简单。只需在 GET 中接受一个名为 callback 的参数即可。

然后将回调 JavaScript 函数包装在您的数据周围。

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

其想法是简单地返回一个 JavaScript 文件,该文件调用回调函数,并将 JSON 对象作为 JavaScript 回调函数的第一个参数。

您可以使用内置的 json_encode() 函数从 PHP 中的数组和对象创建 JSON 字符串(上面示例中的 $data 包含该字符串)。

要使用 JSONP 服务,可以使用

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

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

Then wrap the callback JavaScript function around your data.

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

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.

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.

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

<script>
    function receiver(data){
        console.log(data);
    }
</script>
<script src="data-service.php?callback=receiver"></script>
追星践月 2024-08-17 06:40:28

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

我给你留下了一个使用 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

这是一个小的 JSONP 服务 用于检索 Zach ,它托管在 Google App Engine

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

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

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.

時窥 2024-08-17 06:40:28

莫里斯已经给了你一个可行的例子。我只想补充一点,您应该检查回调参数是否存在且非空,如果不存在,则按原样返回不带括号的 json 数据。所以基本上你的 api 将是 JSON,并在给出回调时提供 JSON-P。

要使用 JSON-P Web 服务,除非您使用 YUI 或 jQuery 等框架,否则您只需动态创建一个脚本节点并将其 src 属性设置为指向 Web 服务即可。请记住在再次重复之前从 dom 中删除该节点,因为该动态脚本节点仅供一次性使用。

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.

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.

可是我不能没有你 2024-08-17 06:40:28

我知道我参加聚会迟到了,并且其中一个答案中有关于代码安全性的评论。这是一篇关于此的好文章:

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

这是您应该运行的代码:

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

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/

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);
喜你已久 2024-08-17 06:40:28
// 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');

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

http://url_to_receiver_script /index.php¶m=anything

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

就像任何浏览器中的时钟一样工作。

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

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

http://url_to_receiver_script/index.php¶m=anything

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

works like a clock in any browser.

迟月 2024-08-17 06:40:28

使用 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]);
  }
}
}

并确保从服务器端获得正确的 json;
并且不要忘记返回 jsonp_callback 参数,否则它将无法工作!!!!!
确实如此。

Easy with jQuery,
that is the client side:

  $.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.

來不及說愛妳 2024-08-17 06:40:28

您可以使用 Simple JSON for 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();
?>

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

<?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();
?>
尾戒 2024-08-17 06:40:28

例子在这里
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>

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

<script src=".../example2...?output=json;callback=loadit"></script>
<script>
alert( "I got this from example2 " + loadit);
</script>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文