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

为什么默认情况下不允许返回JSON的GET请求?

  •  33
  • Jedidja  · 技术社区  · 16 年前

    作为ASP的一部分。NET MVC 2 Beta 2更新,默认情况下不允许JSON GET请求。您似乎需要设置 JsonRequestBehavior JsonRequestBehavior.AllowGet JsonResult

    public JsonResult IsEmailValid(...)
    {
        JsonResult result = new JsonResult();
    
        result.Data = ..... ;
        result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    
        return result;
    }
    

    这背后的原因是什么?如果我使用JSON GET尝试进行一些远程验证,我应该使用不同的技术吗?

    4 回复  |  直到 12 年前
        1
  •  23
  •   TJB    16 年前

    DenyGet默认值的原因是打开 MSDN 链接到 Phil Haack's blog 了解更多详情。看起来像是跨站点脚本漏洞。

        2
  •  8
  •   Annabelle    16 年前

    默认情况下,HTTP GET作为ASP的一部分被禁用。NET的跨站点请求伪造(CSRF/XSRF)保护。如果您的web服务接受GET请求,那么它们可能容易受到第三方网站通过以下方式发出请求的攻击 <script /> 标签,并可能通过修改JavaScript设置程序来获取响应。

    然而,值得注意的是,禁用GET请求不足以防止CSRF攻击,也不是保护您的服务免受上述攻击类型的唯一方法。看 Robust Defenses for Cross-Site Request Forgery 以便很好地分析不同的攻击媒介以及如何防御它们。

        3
  •  3
  •   Junior Mayhé    16 年前

    当我将MVC网站从Visual Studio 2008迁移到Visual Studio 2010时,我也遇到了你的问题。

    主aspx如下,它有一个ViewData,它调用一个类别控制器,用SelectList集合填充ViewData[“类别”]。还有一个脚本可以调用子类别控制器,用javascript填充第二个组合。现在,我能够通过在第二个控制器上添加AlloGet属性来修复它。

    这是aspx和javascript

    <head>
    <script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function () {
    $("#CategoryId").change(function () {
    
        var categoryId = $(this)[0].value;
    
        $("#ctl00_MainContent_SubcategoryId").empty();
        $("#ctl00_MainContent_SubcategoryId").append("<option value=''>-- select a category --</option>");
        var url = "/Subcategory/Subcategories/" + categoryId;
    
        $.getJSON(url, { "selectedItem": "" }, function (data) {
            $.each(data, function (index, optionData) {
                $("#ctl00_MainContent_SubcategoryId").append("<option value='" + optionData.SubcategoryId + "'>" + optionData.SubcategoryName + "</option>");
            });
            //feed our hidden html field
            var selected = $("#chosenSubcategory") ? $("#chosenSubcategory").val() : '';
            $("#ctl00_MainContent_SubcategoryId").val(selected);
    
        });
    
    }).change();
    });
    </script>
    <body>
    <% using (Html.BeginForm()) {%>
    <label for="CategoryId">Category:</label></td>
    <%= Html.DropDownList("CategoryId", (SelectList)ViewData["Categories"], "--categories--") %>
    <%= Html.ValidationMessage("category","*") %>
    <br/>
    <label class="formlabel" for="SubcategoryId">Subcategory:</label><div id="subcategoryDiv"></div>
    <%=Html.Hidden("chosenSubcategory", TempData["subcategory"])%>
    <select id="SubcategoryId" runat="server">
    </select><%= Html.ValidationMessage("subcategory", "*")%>
    <input type="submit" value="Save" />
    <%}%>                
    

    这是我的子类别控制器

    public class SubcategoryController : Controller
    {
        private MyEntities db = new MyEntities();
    
        public int SubcategoryId { get; set; }
        public int SubcategoryName { get; set; }
        public JsonResult Subcategories(int? categoryId)
        {
            try
            {
                if (!categoryId.HasValue)
                    categoryId = Convert.ToInt32(RouteData.Values["id"]);
                var subcategories = (from c in db.Subcategories.Include("Categories")
                                     where c.Categories.CategoryId == categoryId && c.Active && !c.Deleted
                                      && c.Categories.Active && !c.Categories.Deleted
                                     orderby c.SubcategoryName
                                     select new { SubcategoryId = c.SubcategoryId, SubcategoryName = c.SubcategoryName }
                );
                //just added the allow get attribute
                return this.Json(subcategories, JsonRequestBehavior.AllowGet);
            }
            catch { return this.Json(null); }
    
        }
    
        4
  •  2
  •   StriplingWarrior    16 年前

    我不知道这是否是他们选择更改默认值的原因,但这是我的经验:

    当一些浏览器看到GET时,他们认为可以缓存结果。由于AJAX通常用于从服务器获取最新信息的小请求,因此缓存这些结果通常会导致意外行为。如果你知道给定的输入每次都会返回相同的结果(例如,无论你什么时候问我,“密码”都不能用作密码),那么GET就可以了,浏览器缓存实际上可以提高性能,以防有人多次尝试验证同一输入。另一方面,如果您希望根据服务器端数据的当前状态得到不同的答案(“myfavoriteusername”可能在2分钟前就可用了,但从那以后就被使用了),您应该使用POST来避免浏览器认为第一个响应仍然是正确的。

    推荐文章