parsererror после запроса jQuery.ajax с типом содержимого jsonp
Я использую jQuery версии 1.5.1 для выполнения следующего вызова ajax:
$.ajax({
dataType: 'jsonp',
data: { api_key : apiKey },
url: "http://de.dawanda.com/api/v1/" + resource + ".json",
success: function(data) { console.log(data); },
error: function(jqXHR, textStatus, errorThrown) { console.log(errorThrown); console.log(textStatus); }
});
Сервер отвечает допустимым объектом json:
{
"response": {
"type":"category",
"entries":1,
"params":{
"format":"json",
"api_key":"c9f11509529b219766a3d301d9c988ae9f6f67fb",
"id":"406",
"callback":"jQuery15109935275333671539_1300495251986",
"_":"1300495252693"
},
"pages":1,
"result":{
"category":{
"product_count":0,
"id":406,
"restful_path":"/categories/406",
"parent_id":null,
"name":"Oberteile"
}
}
}
}
Но обратный вызов успеха никогда не вызывается, вместо этого обратный вызов ошибки производит такой вывод:
jQuery15109935275333671539_1300495251986 was not called
parsererror
Почему это происходит?
Я не использую дополнительные библиотеки для jQuery.
РЕДАКТИРОВАТЬ:
Если я попытаюсь сделать вызов ajax с "json" в качестве dataType вместо "jsonp", сервер ответит пустой строкой.
10 ответов
JSONP требует, чтобы ответ был обернут в какую-то функцию обратного вызова, потому что он работает, внедряя тег script в документ в качестве механизма загрузки данных из другого домена.
По сути, происходит то, что тег скрипта динамически вставляется в документ следующим образом:
<script src="http://the.other.server.com/foo?callback=someFn"></script>
callback
зависит от ресурса, который вы вызываете, для параметра характерно callback
хоть.
someFn
затем используется для обработки возвращенных данных с сервера, поэтому сервер должен ответить:
someFn({theData: 'here'});
SomeFn передается как часть запроса, поэтому сервер должен прочитать его и соответствующим образом обернуть данные.
Все это при условии, что вы получаете контент из другого домена. Если это так, вы ограничены той же политикой происхождения: http://en.wikipedia.org/wiki/Same_origin_policy
После обновления до Jquery 1.5 и попытки сделать звонок через домены у меня возникла та же проблема. В конце концов я обнаружил, что $.getJSON сработал. В частности,
$.getJSON(url,
function(data){
yourFunction(data);
return false;
});
URL, который я использовал, был таким:
var url = WEB_SERVER_URL;
url = url + "&a=" + lat;
url = url + "&b=" + lng; ....
url = url + "&jsoncallback=?";
На сервере, который работает на другом сервере и у меня есть контроль над этим кодом был добавлен:
PrintWriter writer = response.getWriter();
String jsonString = json.toString(JSON_SPACING);
String callback = request.getParameter("jsoncallback");
// if callback in URL and is not just the "?" (e.g. from localhost)
if (callback != null && callback.length() > 1)
{
writer.write(callback + "(" + jsonString + ");");
}
else
{
writer.write(jsonString);
}
(Объект json является экземпляром JSONObject, код можно найти здесь http://www.json.org/java/)
Когда вы используете jsonp в качестве типа данных (создание междоменного запроса), Jquery генерирует случайную функцию и добавляет URL к запрошенной строке запроса с именем callback (callback=?), вам нужно добавить ответные данные json в качестве параметра этой функции, как показано ниже -
url : http://www.dotnetbull.com/cross-domain-call.ashx?ref=jquery-jsonp-request
url call by ajax :
http://www.dotnetbull.com/cross-domain-call.ashx?ref=jquery-jsonp-request&callback=jQuery1510993527567155793_137593181353
Данные ответа должны выглядеть так:
string callback = context.Request.QueryString["callback"];
if (!string.IsNullOrEmpty(callback))
context.Response.Write(string.Format("{0}({1});", callback, jc.Serialize(outputData)));
else
context.Response.Write(jc.Serialize(outputData));
Подробнее о: parsererror после запроса jquery.ajax с типом контента jsonp
Есть одна маленькая ошибка:) Вы должны запросить.js, а не.json.
$.ajax({
dataType: 'jsonp',
data: { api_key : apiKey },
url: "http://de.dawanda.com/api/v1/" + resource + ".js",
success: function(data) { console.log(data); },
error: function(jqXHR, textStatus, errorThrown) { console.log(errorThrown); console.log(textStatus); }
});
Ах, а вы заметили, что есть клиент для API? https://github.com/dawanda/dawanda-api-client-js
Убедитесь, что вызываемая служба имеет возможность возвращать данные в формате JsonP.
Если вы используете asp.net webapi, вы можете использовать WebApiContrib.Formatting.Jsonp, это с открытым исходным кодом.
Убедитесь, что у вас есть строка, как показано ниже в WebApiConfig.Register.
config.Formatters.Insert (0, новый JsonpMediaTypeFormatter(новый JsonMediaTypeFormatter(), "обратный вызов"));
Я тянул волосы за это. Надеюсь, это кому-нибудь поможет.
Попробуйте прочитать ответ в объект, используя $.parseJSON:
success: function(data) {
var json = $.parseJSON(data);
}
Вы действительно не должны указывать здесь jsonp. Просто используйте json, потому что вы просто получаете строку JSON. JSON (JSON с отступом) ожидает выполнения функции JavaScript. В этом случае вам нужно указать "callback=" в вашей строке запроса. Я думаю, что именно поэтому jQuery не может справиться с этим, есть свойство с обратным вызовом имени.
Спасибо Эван Тримболи.
Добавлены только те изменения, которые я сделал
JSON-обратный вызов =someFun
и изменил имя анонимной функции из
Функция (дл)
в
функция someFun(dl)
Полная строка кода приведена ниже:
getJSON("http://localhost/phk/districtList.json?json-callback=someFun", function someFun(dl){
....
....
}
Та же проблема у меня возникала, пока я не добавил параметр "callback=?" или "с =?" в URL
Например: " http://de.dawanda.com/api/v1/" + resource + ".json & c =?"
Может решить вашу проблему. Это сработало для меня.
Не все серверы поддерживают JSONP. Это требует, чтобы сервер установил функцию обратного вызова в своих результатах. Я использую это для получения ответов json с сайтов, которые возвращают чистый json, но не поддерживают jsonp (но могут в будущем):
function AjaxFeed(){
return $.ajax({
url: 'http://somesite.com/somejsonfile.php',
data: {something: true},
dataType: 'jsonp',
/* Very important */
contentType: 'application/json',
});
}
function GetData()
AjaxFeed()
/* Everything worked okay. Hooray */
.done(function(data){
return data;
})
/* Okay jQuery is stupid manually fix things */
.fail(function(jqXHR) {
/* Build HTML and update */
var data = jQuery.parseJSON(jqXHR.responseText);
return data;
});
}