JSONP请求成功,但不返回任何数据

时间:2012-03-08 15:36:18

标签: jquery asp.net-mvc-2

我无法从我的某个网站检索JSONP数据。现场数据由以下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
    }
});

我可以在Firebug控制台中看到响应使用200代码正确完成,我可以看到响应的内容长度为11516字节,但响应选项卡完全为空,jQuery不会给我任何数据与...合作。

谁能告诉我为什么会这样?

注意:此站点使用的是jQuery 1.4.2

2 个答案:

答案 0 :(得分:3)

您正在返回与JSONP不同的JSON:

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

您在客户端上设置dataType: 'JSONP'的事实只是您需要完成的工作的一半。下半部分在服务器上。

查看following answer,其中说明了如何创建自定义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);
    }
});

答案 1 :(得分:2)

你给出的回应不是JSONP ..它是JSON。 JSONP需要包装在函数名中;

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

可以在this answer中看到有关为什么JSONP需要在函数名称中包围(即填充)以及如何绕过SOP限制的更多详细信息。

要在ASP.NET中返回JSONP,您似乎需要手动执行此操作,例如在此问题中; ASP.net MVC returning JSONP

在你的情况下,你甚至不应该看到“成功”警报;但这是你正在使用的jQuery版本中的一个错误(1.4.2)。通过jQuery不支持crossDomain直到1.5,并且它专门检查dataType jsonp(而不是JSONP),最终你最终在{{{}}上发出标准的JSON请求{1}},浏览器正在中止以强制执行SOP。但是,jQuery是misinterpreting the state of the aborted object as completed

最终,这会导致调用success处理程序,而XMLHttpRequest未初始化(data)。