Рекомендация для jQuery JSONP
В документах для $.getJSON
и $.ajax
раздел jsonp отмечает, что вы можете явно указать имя функции обратного вызова с помощью jsonpCallback
свойство config.Поэтому, если вы хотите, чтобы JsonWrapping(...)
была функцией, ожидаемой jquery внутри ответа jsonp, вы можете связать вещи обратно так:
$.ajax({
url: 'http://blah.com/blah.json',
dataType: 'jsonp',
cache: true,
jsonpCallback: 'JsonWrapping'
})
.done(function(r) {
status.text('It worked.');
})
.fail(function (a, b, c) {
status.text('It failed.');
});
В приведенном выше примере ожидаемая функция обратного вызова внутри ответа jsonp имеет видтеперь JsonWrapping()
, который jQuery будет выдавать для вас, ответит, позвонив .done()
выше и очистив после себя - намного чище, чем жесткое кодирование JsonWrapping
на странице.
Опасности жесткого кодированияи предложения по именованию
Важно учитывать, что если вы планируете иметь много вызовов jsonp на одной странице, а ваши функции переноса jsonp жестко запрограммированы в файлах jsonp, вам следует как минимум изменить свою функцию переноса.чем-то вроде имени файла.В противном случае вы создаете проблему асинхронности.Например, предположим, что у вас был такой код:
function jsonp(url) {
return $.ajax({
url: url,
dataType: 'jsonp'
cache: true,
jsonpCallback: 'JsonWrapping'
});
}
jsonp('http://cdn.mine/one.jsonp')
.done(...);
jsonp('http://cdn.mine/two.jsonp')
.done(...);
Один из этих вызовов jsonp завершится раньше другого - невозможно узнать, какой именно - и jQuery находится в невозможной ситуации, когда он не может знать, какой.done()
для вызова какого ответа.В результате вы получите несколько загрузок страниц там, где они вызываются правильно, а некоторые - когда данные перекрещиваются.Решение состоит в том, чтобы изменить что-то вроде имени файла, например:
function jsonp(url, wrapper) {
return $.ajax({
url: url,
dataType: 'jsonp'
cache: true,
jsonpCallback: wrapper
});
}
jsonp('http://cdn.mine/one.jsonp', 'one')
.done(...);
jsonp('http://cdn.mine/two.jsonp', 'two')
.done(...);
Так что ответ от two.jsonp должен выглядеть следующим образом:
two({...json object here...})
Как это работает
Вызов в начале этого ответа заставит jQuery запросить URL через GET следующим образом:
http://blah.com/blah.json?callback=JsonWrapping
И ожидать это как ответ:
JsonWrapping({...object here...})
Я включил cache: true
выше, потому что это находится в CDN, и, следовательно, предположительно не должно меняться очень часто.Если вы пропустите cache: true
, jQuery вставит второй параметр строки запроса, предназначенный для очистки кэша, например:
http://blah.com/blah.json?callback=JsonWrapping&_=1365175172440
, который может испортить точку CDN.Целью второго параметра querystring является обеспечение того, чтобы данные не загружались из кэша браузера, и когда он попадает на сервер (в данном случае CDN), строка запроса уникальна, то есть он также отключает свой кэш.
За пределами вашего сценария, в котором вы используете CDN, бывают ситуации, когда желаемая функциональность по умолчанию в jQuery: например, когда вы хотите смоделировать функциональность POST в другом домене, не нарушая политику Same-Origin, jsonp с этимФункция очистки кеша может сделать это за вас.
Если сервер, с которым вы разговариваете, ожидает что-то иное, чем «обратный вызов» в строке запроса для указания имени функции обратного вызова в ответе, вы можете использоватьjsonp
свойство config - например, jsonp: 'myname'
даст вам:
http://blah.com/blah.json?myname=JsonWrapping