代码之家  ›  专栏  ›  技术社区  ›  swilliams

jquery-ajax和处理不同的数据类型

  •  10
  • swilliams  · 技术社区  · 17 年前

    我正在使用ASP.NET MVC,但这适用于任何框架。

    我正在对我的服务器进行Ajax调用,大多数情况下它会返回普通的旧HTML,但是如果出现错误,我希望它返回带有状态消息的JSON对象(以及其他一些事情)。似乎没有办法 dataType jquery调用中的选项来处理此问题。默认情况下,它似乎将所有内容解析为HTML,从而导致 <div> 正在填充 "{ status: 'error', message: 'something bad happened'}" .

    [编辑]忽略 数据库类型 对象和让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'
    });
    

    然而,以这种方式使用一个例外对我来说是一个相当糟糕的设计(至少说是非必然的)。有更好的方法吗?我考虑将整个响应包装在一个JSON对象中,但是在这种情况下,我不认为这是一个选项。

    以下是我从史蒂夫·威尔科克那里得到的解决方案:

    // 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'
    });
    
    6 回复  |  直到 12 年前
        1
  •  9
  •   Steve Willcock    17 年前

    对于JSON错误,您可以从服务器返回500个状态代码,而不是200个。然后jquery客户机代码可以使用$.Ajax函数上的error:handler进行错误处理。在500响应上,您可以从responseText解析JSON错误对象,在200响应上,您可以像正常一样将HTML放入DIV中。

        2
  •  6
  •   Paolo Bergantino    17 年前

    虽然史蒂夫的想法是好的,但为了完整起见,我把它加进去了。

    如果您指定JSON的数据类型但返回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指定为数据类型,jQuery(1.3.2)发现它不是这样的。

    $.ajax({
        url: 'php.php?type=json',
        dataType: 'json',
        success: function(d) {
            console.log(typeof d); // 'object'
        }
    });
    

    所以你可以利用这个(据我所知)无证行为来做你想做的。

        3
  •  3
  •   andi    17 年前

    但是为什么不只返回JSON,而不考虑日志上的状态(成功或错误),并使用GET来显示结果呢?
    如果你问我,这似乎是个更好的办法。

        4
  •  0
  •   jaminto    15 年前

    或者,您可以始终返回一个JSON响应,并使用一个参数作为HTML内容。

    类似:

    {
         "success" : true,
         "errormessage" : "",
         "html" : "<div>blah</div>",
    }
    

    我认为您只需要在HTML值中转义双引号,而JSON解析器将为您撤消该操作。

        5
  •  0
  •   contactmatt    14 年前

    我在mvc/ajax/jquery中遇到了同样的问题,我希望使用多个数据类型(json和html)。我有一个使用HTML数据类型返回数据的Ajax请求,但是我尝试将从Ajax请求返回的数据转换为JSON对象。我有一个这样的函数,我从成功回调调用它:

        _tryParseJson: function (data) {
            var jsonObject;
    
            try {
                jsonObject = jQuery.parseJSON(data);
            }
            catch (err) {
            }
    
            return jsonObject;
        }
    

    然后,我假设如果存在jsonObject和ErrorMessage属性,则会发生错误,否则不会发生错误。

        6
  •  0
  •   ubergoober    12 年前

    我只是通过使用Ajax成功回调和错误回调来实现这一点。通过这种方式,我可以混合使用来自服务器的字符串和JSON对象响应。

    下面我准备接受JSON,但是如果我得到“parserror”的状态(这意味着jquery不能将传入的代码解析为json,因为这正是我所期望的),但是它得到了“OK”(200)的请求状态,那么我将以字符串的形式处理响应。除了“parserror”和“ok”之外的任何东西,我都当作一个错误来处理。

    $.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');
          }
        }
      });