JSONP request successful, but returns no data

I'm having trouble retrieving JSONP data from one of my sites. On Site A data is being provided by the following MVC2 controller action:

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");
}

On Site B, I'm using jQuery to retrieve the JSON, like this:

$.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 can see in the Firebug console that the response completed correctly with a 200 code, and I can see that the content length of the response is 11516 bytes, yet the response tab is completely empty and jQuery will not give me any data to work with.

Can anyone tell me why this is?

Note: This site is using jQuery 1.4.2


You are returning JSON which is not the same as JSONP:

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

The fact that you set dataType: 'JSONP' on the client is only half of the work that you need to do. The second half is on the server.

Checkout the following answer which illustrates how you could create a custom JsonpResult which will use the callback query string parameter to wrap the response into JSONP.

So:

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);
    }
}

and then:

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);
}

and on the client:

$.ajax({
    url: 'http://www.siteA.com/controller/jsonaction/',
    jsonp: 'callback',
    dataType: 'jsonp',
    success: function (json) {
        alert(json);
    }
});

The response you're giving is not JSONP.. it's JSON. JSONP needs to be wrapped in a function name;

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

More details on why JSONP needs to be surrounded in a function name (ie the padding), and how it bypasses the SOP restrictions can be seen in this answer.

To return JSONP in ASP.NET it seems you need to do it manually, such as in this question; ASP.net MVC returning JSONP

In your case, you shouldn't have even seen the "success" alert; but this was down to a bug in the version of jQuery you're using (1.4.2). By jQuery not supporting crossDomain until 1.5, and it checking specifically for a dataType of jsonp (rather than JSONP ), you ultimately ended up making a standard JSON request over XMLHttpRequest , which the browser was aborting to enforce SOP. However, jQuery was misinterpreting the state of the aborted object as completed.

Ultimately, this led to the success handler being called, whilst data was uninitialized ( "" ).

链接地址: http://www.djcxy.com/p/47512.html

上一篇: JavaScript与jQuery的JSONP跨域请求

下一篇: JSONP请求成功,但不返回任何数据