我有一個兩個域名,example1.com和example2.comJavaScript:如何創建JSONP?
從example1.com,我想調用我在example2.com上的JSON API。知道這是不被允許的,它發生在我身上 - 這正是爲什麼創建JSON P。
問題是,如何修改我的JSON API以使其具有JSONP的能力?
基本上,我該如何創建回調api?
UPDATE
我的服務器端語言是PHP
我有一個兩個域名,example1.com和example2.comJavaScript:如何創建JSONP?
從example1.com,我想調用我在example2.com上的JSON API。知道這是不被允許的,它發生在我身上 - 這正是爲什麼創建JSON P。
問題是,如何修改我的JSON API以使其具有JSONP的能力?
基本上,我該如何創建回調api?
UPDATE
我的服務器端語言是PHP
例如這裏 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>
你需要一個服務器端語言,回調參數是一個簡單的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
這是用於獲取客戶端IP地址的小JSONP service通過Zach使代碼它位於Google App Engine上。
你的代碼工作得很漂亮,太優雅了! – TruMan1 2011-03-18 05:17:52
這個答案應該被接受 – 2012-08-29 09:18:43
很簡單。只需在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;
}
它的想法是簡單地返回其調用與JSON對象的JavaScript回調函數的第一個參數回調函數的JavaScript文件。
您可以使用內置的json_encode()
函數從PHP中的數組和對象創建JSON字符串(其中$data
在我們上面的示例中包含)。
要使用JSONP服務,您可以使用<script>
標籤:
<script>
function receiver(data){
console.log(data);
}
</script>
<script src="data-service.php?callback=receiver"></script>
哇,真的只是簡單嗎? – Teddi 2009-11-05 04:12:30
我是否需要添加:echo'訪問控制 - 允許來源:*' 回聲'訪問控制 - 允許 - 方法:GET'? – Teddi 2009-11-05 04:24:58
@Teddi:這些頭文件支持即將推出的XMLHttpRequest 2規範(http://www.w3.org/TR/access-control/)和BTW,它們已經在Firefox 3.5上工作(https://developer.mozilla.org/en/HTTP_access_control) – CMS 2009-11-05 04:46:01
Mauris已經給了你工作的例子。我只補充一點,你應該檢查一個callback
參數是否存在並且是非空的,如果不是,則返回沒有括號的json數據。所以基本上你的api將會是JSON,當提供callback
時,提供的是JSON-P。
要使用JSON-P webservice,除非使用YUI或jQuery之類的框架,否則可以簡單地創建腳本節點並將其src
屬性設置爲指向web服務。請記住從dom中刪除節點,然後再重複一次,因爲此動態腳本節點只能單獨使用。
易於使用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參數,否則它將不起作用!!!!!
就是這樣。
///回調腳本應該返回回調函數的名稱,也就是說,如果你在瀏覽器中鍵入
http://url_to_receiver_script/index.php¶m=anything
它應該只返回一個文本(的名稱的現有處理功能): addScriptToHead(any_param)
在任何瀏覽器中都像鐘錶一樣工作。
我知道我遲到了派對,並且在其中一個答案中有關於代碼安全性的評論。以下是有關這個好文章:
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);
如果偶然任何人使用angular,這將不起作用。 Angular支持jsonp,但是用'angular.callback._0'來代替回調。會允許這樣的回調不安全嗎? – 2014-02-13 08:50:51
@BobVork我不這麼認爲,你可以改變'$ identifier_syntax'來包含句點。實際上,我相信我在這個實現中因爲這個原因結束了這個工作(但是在完成我的實現之前發佈了這個)。 – jkinz 2014-02-17 18:41:31
可以使用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();
?>
但是上面的例子阻止了... – Kzqai 2014-06-25 15:52:39