1

我有一些 jQuery 可以调用 WCF 服务。当服务遇到错误时,它会抛出一个WebFaultException带有描述和500 Internal Server Error状态代码的。

客户端,我正在做一些事情:

$.ajax({
    url: BaseUrl + 'ThisShouldThrowAnException',
    type: 'GET',
    dataType: 'jsonp',
    crossDomain: true,
    success: function (data) {
        // this should never be called
        alert("Got data: " + data);
    },
    error: function (jqXHR, status, message) { // never called
            // would like this to handle my status code
        alert(status + " " + message);
    }
});

在本地 IIS 服务器上,正在调用的相应代码如下所示:

[OperationContract]
[WebGet(RequestFormat=WebMessageFormat.Json)]
bool ThisShouldThrowAnException();


public bool ThisShouldThrowAnException()
{
    throw new WebFaultException<String>("Something really bad happened.", HttpStatusCode.InternalServerError);
}

问题是,当我进行此调用时,将调用成功函数。jQuery 似乎吞噬了我500 Internal Server Error,而是给了我一个200 OK. 使用Fiddler进行检查还显示我的响应状态代码是200 OK. 当我通过浏览器调用或手工制作请求时,我会收到相应的500 Internal Server Error.

我的问题是:我怎样才能处理呼叫的WebExceptionFault内部$.ajax(...)?就目前$.ajax而言,它完全忽略了传递给它的任何状态代码。

我尝试使用ajaxErrorand statusCode,但都没有奏效:

$('#error').ajaxError(function() {
    alert("An error occurred");
});

$.ajax({
    url: BaseUrl + 'ThisShouldThrowAnException',
    type: 'GET',
    dataType: 'jsonp',
    crossDomain: true,
    success: function (data) {
        alert("Got data: " + data);
    },
    statusCode: {
        500: function() {
            alert("Got 500 Internal Server Error");
        }
    },
    error: function (jqXHR, status, message) {
        alert(status + " " + message);
    }
});

新发现

在进一步分析中,当我检查 jQuery 生成的查询字符串时,我发现以下返回一个200 OK

http://localhost/RestService/RestService.svc/ThisShouldThrowAnException?callback=jQuery172003801283869839445_1341495740773&_=1341495740777

// on page:
jQuery172003801283869839445_1341495740773("Something really bad happened.",500);

同时,以下请求返回一个500 Internal Server Error

http://localhost/RestService/RestService.svc/ThisShouldThrowAnException

// on page:
"Something really bad happened"
4

2 回答 2

1

http://api.jquery.com/jQuery.ajax/

在数据类型部分下,他们提到

jsonp 类型附加一个查询字符串参数 callback=? 到网址。服务器应在 JSON 数据前面加上回调名称,以形成有效的 JSONP 响应。我们可以使用 $.ajax() 的 jsonp 选项指定回调以外的参数名称。

当从远程服务器检索数据时(只能使用脚本或 jsonp 数据类型),永远不会触发错误回调和全局事件。

这就是为什么您的错误回调没有触发并且它直接转到成功回调的原因。

编辑:成功函数中的数据是什么样的?因为据我了解,从服务器返回的任何内容都作为数据传入。

这是使用 JSONP 使用 WCF Web 服务的示例。

http://bendewey.wordpress.com/2009/11/24/using-jsonp-with-wcf-and-jquery/

关键是,WCF 看到您正在请求 JSONP 数据,并且您提供了一个名为“回调”的查询字符串参数。因此,WCF 会自动返回 200 OK(无论实际状态如何)以及远程函数返回的任何数据。

进一步阅读 JSONP 的实际工作原理: http ://devlog.info/2010/03/10/cross-domain-ajax/

如果您阅读了 JSONP 的工作原理,您会意识到 jQuery 不太可能返回实际的错误状态,因为服务器本身不会返回它。

关于您当前的问题,请切换到 JSON 请求。如果这不可能,您可以随时检查 ajax 成功函数中的数据对象。当您返回它时,它将具有错误代码 500。

于 2012-07-06T03:15:47.903 回答
1

错误处理程序不会为jsonp请求触发。jQuery ajax文档对error(jqXHR, textStatus, errorThrown)有以下免责声明:

注意:跨域脚本和 JSONP 请求不调用此处理程序。

如果您可以选择切换到jsoncrossDomain=false,则应该触发错误处理程序。

这里有一个关于这个主题的类似问题

这个SO question 建议在服务器上捕获任何错误,始终返回 200 并在有效负载中返回响应代码。

于 2012-07-06T00:46:05.760 回答