我正在使用ASP.Net MVC,但这适用于任何框架。
我正在对我的服务器进行Ajax调用,大部分时间都会返回普通的旧HTML,但是如果出现错误,我希望它返回一个带有状态消息的JSON对象(以及其他一些)事情)。似乎没有办法让jQuery调用中的dataType
选项能够很好地处理这个问题。默认情况下,它似乎将所有内容解析为html,导致<div>
填充"{ status: 'error', message: 'something bad happened'}"
。
[编辑]忽略dataType
对象并让jQuery弄明白也不起作用。它将结果的类型视为string
,并将其视为HTML。
我想出的一个解决方案是尝试将结果对象解析为JSON。如果可行,我们知道它是一个JSON对象。如果它抛出异常,那就是HTML:
$.ajax({
data: {},
success: function(data, textStatus) {
try {
var errorObj = JSON.parse(data);
handleError(errorObj);
} catch(ex) {
$('#results').html(data);
}
},
dataType: 'html', // sometimes it is 'json' :-/
url: '/home/AjaxTest',
type: 'POST'
});
但是,以这种方式使用Exception会让我感觉非常糟糕(至少可以说是不直观的)。有没有更好的办法?我想把整个响应包装在一个JSON对象中,但在这种情况下,我认为这不是一个选择。
这是我从Steve Willcock那里得到的解决方案:
// ASP.NET MVC Action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AjaxTest(int magic) {
try {
var someVal = GetValue();
return PartialView("DataPage", someVal);
} catch (Exception ex) {
this.HttpContext.Response.StatusCode = 500;
return Json(new { status = "Error", message = ex.Message });
}
}
// jQuery call:
$.ajax({
data: {},
success: function(data, textStatus) {
$('#results').html(data);
},
error: function() {
var errorObj = JSON.parse(XMLHttpRequest.responseText);
handleError(errorObj);
},
dataType: 'html',
url: '/home/AjaxTest',
type: 'POST'
});
答案 0 :(得分:9)
对于您的JSON错误,您可以从服务器而不是200返回500状态代码。然后,jquery客户端代码可以使用$ .ajax函数上的error:handler进行错误处理。在500响应中,您可以从responseText解析JSON错误对象,对于200响应,您可以正常地在div中打包HTML。
答案 1 :(得分:6)
虽然史蒂夫的想法很好,但为了完整起见,我加入了这个想法。
看来如果你指定一个json的dataType但是返回HTML,那么jQuery可以很好地处理它。
我用以下代码测试了这个理论:
if($_GET['type'] == 'json') {
header('Content-type: application/json');
print '{"test":"hi"}';
exit;
} else {
header('Content-type: text/html');
print '<html><body><b>Test</b></body></html>';
exit;
}
$_GET['type']
就是这样我可以控制测试时返回的内容。在你的情况下,你会根据事情是对还是错而返回一个或另一个。过去,使用这个jQuery代码:
$.ajax({
url: 'php.php?type=html', // return HTML in this test
dataType: 'json',
success: function(d) {
console.log(typeof d); // 'xml'
}
});
即使我们将JSON指定为dataType,jQuery(1.3.2)也指出它不是那样。
$.ajax({
url: 'php.php?type=json',
dataType: 'json',
success: function(d) {
console.log(typeof d); // 'object'
}
});
所以你可以利用这个(据我所知)无证据的行为来做你想做的事。
答案 2 :(得分:3)
但是,为什么不返回JSON而不管POST上的状态(成功或错误)以及使用GET来显示结果?如果你问我,这似乎是一种更好的方法。
答案 3 :(得分:0)
或者您总是可以返回JSON响应,并且有一个参数作为HTML内容。
类似的东西:
{
"success" : true,
"errormessage" : "",
"html" : "<div>blah</div>",
}
我认为你只需要在html值中转义双引号,而json解析器会为你撤消它。
答案 4 :(得分:0)
我遇到了与MVC / Ajax / JQuery完全相同的问题,并且想要使用多个dataTypes(JSON和HTML)。我有一个AJAX请求使用HTML dataType来返回数据,但我尝试将从ajax请求返回的数据转换为JSON对象。我有一个这样的函数,我从成功回调中调用:
_tryParseJson: function (data) {
var jsonObject;
try {
jsonObject = jQuery.parseJSON(data);
}
catch (err) {
}
return jsonObject;
}
然后我假设如果存在jsonObject和errorMessage属性,则发生错误,否则不会发生错误。
答案 5 :(得分:0)
我通过仅使用ajax成功和错误回调来完成此操作。这样我可以从服务器获得混合字符串和json对象响应。
下面我准备接受json,但如果我得到了#34; parsererror&#34; (意思是jquery无法将传入的代码解析为json,因为那是我所期待的),但它的请求状态为&#34; OK&#34; (200),然后我将响应处理为字符串。除了&#34; parsererror&#34;之外的任何东西和&#34;好的&#34;,我处理错误。
$.ajax({
dataType: 'json',
url: '/ajax/test',
success: function (resp) {
// your response json object, see if status was set to error
if (resp.status == 'error') {
// log the detail error for the dev, and show the user a fail
console.log(resp);
$('#results').html('error occurred');
}
// you could handle other cases here
// or use a switch statement on the status value
},
error: function(request, status, error) {
// if json parse error and a 200 response, we expect this is our string
if(status == "parsererror" && request.statusText == "OK") {
$('#results').html(request.responseText);
} else {
// again an error, but now more detailed and not a parser error
// and we'll log for dev and show the user a fail
console.log(status + ": " + error.message);
$('#results').html('error occurred');
}
}
});