使用jQuery Ajax调用时最佳做法是什么?

时间:2010-02-03 02:56:13

标签: jquery asp.net-mvc ajax

我正在为一位同事审查一些代码,虽然我正在查看的jQuery Ajax调用没有任何内在的错误的,但我想更加确定应该和不应该出现的内容在对ASP.Net MVC控制器操作的正常Ajax调用中。

例如,在以下代码中:

    $(function() {
        $.ajax({
            url: "/Controller/action",
            type: "POST",
            data: ({ myObjectOrParameters }),
            success: function(data) { alert(data); }
        });
    });

这种模式是否正常,还是还有其他东西应该存在? contentType是否可取?那么dataFilter呢?这是不必要的,因为我们不使用Microsoft Ajax并且不关心它返回的“.d”,我是否应该担心?

type怎么样?最佳做法是在阅读或更新信息时使用“GET”甚至“PUT”,还是在每种情况下最适合使用“POST”?

在每种情况下使用$.ajaxSetup更合适,还是我们每次都能明确定义我们的参数?

3 个答案:

答案 0 :(得分:6)

叫我一个简洁的人......

我更希望看到本案例中使用的$.post()方法。除非您在$.ajax()中使用更深奥的选项,否则当有更短且更简洁的方法时,我认为没有任何理由使用它:

$.post("/Controller/action", { myObjectOrParameters }, function(data) {
  alert(data);
});

答案 1 :(得分:5)

如前所述,您提出的请求类型取决于要采取的行动类型。

  • GET:系统的状态应该是 不被改变(凯尔写道, 幂等)。
  • POST:发送数据 将更新的值或状态 系统。

是其他类型的请求HEAD,DELETE等。但是,这些在RESTful开发之外并不常用(http://en.wikipedia.org/wiki/Representational_State_Transfer)。

我在开发依赖于javascript / ajax的网站时一直使用的做法是在jQuery之上为网站开发自定义javascript框架。该库将处理特定于网站的常用功能。例如,你的问题是关于jQuery的ajax函数。特定于您的网站的一些常见功能可能是:显示错误消息,处理意外错误代码(500,404等),向调用添加公共参数以及数据传输类型(JSON,XML等)。

网站的简单自定义JavaScript框架可能如下所示:

(function ($) {
    if (!window.myWebsite) { window.myWebsite = {}; }

    //  once myWebsite is defined in the "window" scope, you don't have
    //  to use window to call it again.
    $.extend(myWebsite, {
        get: function (url, data, callback) {
            myWebsite._ajax(url, data, "GET", callback);
        },

        post: function (url, data, callback) {
            myWebsite._ajax(url, data, "POST", callback);
        },

        _ajax: function (url, data, type, callback) {
            //  http://api.jquery.com/jQuery.ajax/
            $.ajax({
                type: type,
                url: url,
                data: data,
                dataType: 'json',
                success: function(data, status, request) {
                    //  I'll talk about this later. But, I'm assuming that the data
                    //  object returned from the server will include these fields.
                    if( data.result == 'error' ) {
                        myWebsite._displayError( data.message );
                    }

                    //  if no error occured then the normal callback can be called
                    if( $.isFunction(callback) )
                        callback();
                },
                error: function (request, status, error) {
                    myWebsite._displayError( error );        

                    //  you can also use this common code for handling different
                    //  error response types. For example, you can handle a
                    //  500 "internal server error" differently from a 404
                    //  "page not found"
                }
            });
        },

        _displayError: function( text ) {
            //  Many pages have a common area
            //  defined to display error text, let's call that
            //  area <div id="errorDiv" /> on your website
            $('#errorDiv').text(error);
        }
    });
})(jQuery);

您可以从页面调用自定义javascript,如下所示:

myWebsite.get( '/Controller/Action', {}, function() { ... } );

一旦你有了基本的javascript框架,你就可以在ASP.NET MVC项目中添加类,这将返回框架所期望的数据。在上面的javascript中,_ajax函数有一个成功函数,它需要一个包含属性'result'和'message'的JSON对象。这可以通过MVC模型中的基类来实现。

using System;

/// <summary>
/// <para>
/// Encapsulates the common/expected properties for the JSON results
/// on this website.
/// </para>
/// <para>
/// The <see cref="result" /> property should contain the value 'success', when
/// all processing has gone well. If the action has either 'fail'ed or has an 'error'
/// then the <see cref="message"/> property should also be filled in.
/// </para>
/// </summary>
public abstract class JsonResultBase
{

    #region constructors

    /// <summary>
    /// Creates a basic <see cref="JsonResultBase"/> with a 'success' message.
    /// </summary>
    public JsonResultBase()
        : this("success", string.Empty) { }

    /// <summary>
    /// Creates a <see cref="JsonResultBase"/> with the <see cref="result"/> and <see cref="message"/>
    /// properties initialized. This should be used when creating a 'fail'
    /// result.
    /// </summary>
    /// <param name="result">The result type: 'sucess', 'fail', or 'error'.</param>
    /// <param name="message">The message which described why the result occured.</param>
    public JsonResultBase(string result, string message)
    {
        if (result != "success" && string.IsNullOrEmpty(message))
        {
            throw new ArgumentException("message", "message must have a value when the result is not 'success'.");
        }

        this.result = result;
        this.message = message;
    }

    /// <summary>
    /// Creats a <see cref="JsonResultBase"/> which translates an exception into
    /// an error message for display on the webpage.
    /// </summary>
    /// <param name="e">The exception to send back.</param>
    public JsonResultBase(Exception e)
    {
        this.result = "error";
        this.message = e.Message;
    }

    #endregion

    #region properties

    /// <summary>
    /// The result of the action. This could contain the value of 'success', 'fail', or 'error'.
    /// Or, some other values that you define.
    /// </summary>
    public string result { get; set; }

    /// <summary>
    /// Any extra information which would be helpful to describe a result. This will always be
    /// populated if the result is not 'success'.
    /// </summary>
    public string message { get; set; }

    #endregion

}

然后可以扩展该基类以返回呼叫的特定数据并在控制器中使用。

public class HomeController : Controller
{

    private class ValuesJsonResult : JsonResultBase {
        public ValuesJsonResult() : base() {}
        public ValuesJsonResult(Exception e) : base(e) {}

        public string[] values  = new string[0];
    }

    public ActionResult GetList() {
        try {
            return Json(
                new ValuesJsonResult{ values = new [] { "Sao Paulo", "Toronto", "New York" } },
                JsonRequestBehavior.AllowGet
            );
        } catch( Exception e ) {
            //  Opps, something went wrong
            return Json( new ValuesJsonResult(e), JsonRequestBehavior.AllowGet );
        }
    }

}

HTH

答案 2 :(得分:4)

使用GET进行的请求应该是幂等。(意味着如果重复这些请求,净效果是相同的)。幂等查询的简单子集是没有副作用的查询。例如搜索查询。一个好的经验法则是更新用户状态的事情应该是POST。谷歌有关GET与POST的更多信息。

您缺少的另一个最佳做法是错误处理程序。这会处理500或403服务器错误以响应请求,这是必不可少的。