Каковы лучшие практики при использовании вызовов jQuery Ajax? - PullRequest
5 голосов
/ 03 февраля 2010

Я проверяю некоторый код для коллеги, и, хотя нет ничего по сути не так с вызовами jQuery Ajax, на которые я смотрю, я бы хотел быть более уверенным в том, что должно и не должно появляться в обычный Ajax-вызов действия контроллера ASP.Net MVC.

Например, в следующем коде:

    $(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 ]

6 голосов
/ 03 февраля 2010

Назовите меня кратким человеком ...

Я бы предпочел увидеть метод $.post(), используемый в этом случае.Если вы не используете более эзотерические опции в $.ajax(), я не вижу смысла использовать его, когда есть более короткие и более лаконичные методы:

$.post("/Controller/action", { myObjectOrParameters }, function(data) {
  alert(data);
});
6 голосов
/ 03 февраля 2010

Как уже упоминалось в предыдущих публикациях, тип запроса зависит от типа действия.

  • GET: состояние системы должно не быть измененным (как писал Кайл, идемпотентная).
  • POST: отправка данных, которые обновит значение или состояние система.

Это другие типы запросов HEAD, DELETE и т. Д. Но они обычно не используются вне разработки RESTful (http://en.wikipedia.org/wiki/Representational_State_Transfer).

Практика, которую я использовал при разработке веб-сайта, основанного на javascript / ajax, заключается в разработке пользовательской структуры javascript для веб-сайта поверх jQuery. Библиотека будет обрабатывать общие функциональные возможности, характерные для веб-сайта. Например, у вас вопрос о функции 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 имеет функцию успеха, которая ожидает объект 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 );
        }
    }

}

НТН

4 голосов
/ 03 февраля 2010

Запросы, сделанные с помощью GET, должны быть идемпотентными. (Это означает, что если они повторяются, суммарный эффект тот же).Простое подмножество идемпотентных запросов - это те, которые не имеют побочных эффектов.например, поисковый запрос.Хорошее практическое правило заключается в том, что вещи, которые обновляют состояние пользователя, должны быть POST.Google для получения дополнительной информации о GET против POST.

Еще одна лучшая практика, которую вы пропустите, - это обработчик ошибок.Это обрабатывает такие вещи, как ошибка сервера 500 или 403 в ответ на запрос, и очень важно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...