Запрос JSONP выполнен успешно, но данные не возвращаются - PullRequest
3 голосов
/ 08 марта 2012

У меня проблемы с получением данных JSONP с одного из моих сайтов.На сайте A данные предоставляются следующим действием контроллера MVC2:

public JsonResult JsonList(string key) {
    var consultants = rep.FindAll().Where(c => c.IsActive).Select(c => new ConsultantJsonItem { Firstname = c.Firstname, Surname = c.Surname });

    return Json(consultants, "application/json");
}

На сайте B я использую jQuery для извлечения JSON, например:

$.ajax({
    url: 'http://www.siteA.com/controller/jsonaction/',
    dataType: 'JSONP',
    crossDomain: true,
    success: function (json) {
        alert("success"); // THIS DISPLAYS
        alert(json); // THIS IS ALWAYS EMPTY
    },
    error: function (xhr, status, error) {
        alert(status); // NOT CALLED
    }
});

IВ консоли Firebug видно, что ответ завершен правильно с кодом 200, и я вижу, что длина содержимого ответа составляет 11516 байт, однако вкладка ответа полностью пуста, и jQuery не даст мне никаких данных для работы.

Может кто-нибудь сказать мне, почему это так?

Примечание. Этот сайт использует jQuery 1.4.2

.

Ответы [ 2 ]

3 голосов
/ 08 марта 2012

Вы возвращаете JSON, который отличается от JSONP:

return Json(consultants, "application/json");

Тот факт, что вы установили dataType: 'JSONP' на клиенте, - это только половина работы, которую вам нужно сделать. Вторая половина на сервере.

Извлеките следующий ответ , который иллюстрирует, как можно создать пользовательский JsonpResult, который будет использовать параметр строки запроса обратного вызова для переноса ответа в JSONP.

Итак:

public class JsonpResult : ActionResult
{
    private readonly object _obj;

    public JsonpResult(object obj)
    {
        _obj = obj;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var serializer = new JavaScriptSerializer();
        var callbackname = context.HttpContext.Request["callback"];
        var jsonp = string.Format("{0}({1})", callbackname, serializer.Serialize(_obj));
        var response = context.HttpContext.Response;
        response.ContentType = "application/json";
        response.Write(jsonp);
    }
}

и затем:

public ActionResult JsonList(string key) 
{
    var consultants = rep.FindAll().Where(c => c.IsActive).Select(c => new ConsultantJsonItem { Firstname = c.Firstname, Surname = c.Surname });
    return new JsonpResult(consultants);
}

и на клиенте:

$.ajax({
    url: 'http://www.siteA.com/controller/jsonaction/',
    jsonp: 'callback',
    dataType: 'jsonp',
    success: function (json) {
        alert(json);
    }
});
2 голосов
/ 08 марта 2012

Ответ, который вы даете, это не JSONP .. это JSON.JSONP должен быть заключен в имя функции;

foo({ "valid": "json" });

Дополнительные сведения о том, почему JSONP необходимо заключать в имя функции (т. Е. Заполнение), и как он обходит ограничения SOP, можно увидеть в этот ответ .

Чтобы вернуть JSONP в ASP.NET, кажется, вам нужно сделать это вручную, например, в этом вопросе; ASP.net MVC возвращает JSONP

В вашем случае вы даже не должны были видеть предупреждение "успех";но это было связано с ошибкой в ​​используемой версии jQuery (1.4.2).Поскольку jQuery не поддерживает crossDomain до 1.5 и специально проверяет dataType из jsonp (а не JSONP), вы в конечном итоге сделали стандартный JSON-запрос поверх XMLHttpRequest, который браузер прерывалдля обеспечения соблюдения СОП.Однако jQuery неправильно интерпретировал состояние прерванного объекта как завершенное .

В конечном итоге это привело к вызову обработчика success , в то время как data был неинициализирован ("").

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...