JavaScript: Как создать JSONP?
У меня есть два домена, example1.com и example2.com
Из example1.com, я хотел бы назвать JSON API, который у меня есть на example2.com. Зная, что это не разрешено, мне пришло в голову - именно поэтому был создан JSON P.
Вопрос в том, как мне изменить свой JSON API, чтобы он работал с JSONP?
В принципе, как мне создать обратный вызов api?
UPDATE
Мой серверный язык - это PHP
Ответы
Ответ 1
Это просто. Просто принимайте параметр с именем callback
в GET.
Затем заверните функцию 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()
для создания строк JSON (которые $data
в нашем примере выше содержит) из массивов и объектов в PHP.
Чтобы использовать службу JSONP, вы можете использовать тег <script>
:
<script>
function receiver(data){
console.log(data);
}
</script>
<script src="data-service.php?callback=receiver"></script>
Ответ 2
Вам нужен серверный язык, параметр обратного вызова - это просто параметр 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, используемый для извлечения IP-адреса клиента, сделанного Zach, и он размещен на Google App Engine.
Ответ 3
Маурис уже дал вам рабочий пример. Я бы добавил, что вы должны проверить, присутствует ли параметр callback
и не пуст, а если нет, верните json-данные, как есть без круглых скобок. Таким образом, в основном ваш api будет JSON с предоставлением JSON-P, если callback
.
Чтобы использовать веб-сервис JSON-P, если вы не используете фреймворк вроде YUI или jQuery, вы можете просто создать script node динамически и установить его атрибут src
, чтобы указать на веб-сервис. Не забудьте удалить node из dom, прежде чем повторять его снова, так как этот динамический script node используется только один раз.
Ответ 4
Я знаю, что опаздываю на вечеринку, и в одном из ответов был комментарий о безопасности кода. Вот хорошая статья об этом:
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);
Ответ 5
// 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');
///обратный вызов script должен возвращать имя функции обратного вызова, т.е. если вы введете браузер
http://url_to_receiver_script/index.php¶m=anything
он должен возвращать только текст (имя существующей функции обработки): addScriptToHead (any_param)
работает как часы в любом браузере.
Ответ 6
Легко с jQuery,
это клиентская сторона:
$.ajax({
dataType: 'jsonp',
data: "somedata="+somevalue,
//this is very important since it 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, иначе он не будет работать!!!!!
и что это действительно.
Ответ 7
пример здесь
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
Вы можете использовать Simple 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();
?>