【问题标题】:Should I use HTTP Status code to indicate result of AJAX post request?我应该使用 HTTP 状态代码来指示 AJAX 发布请求的结果吗?
【发布时间】:2015-10-06 19:00:30
【问题描述】:

我正在将“创建用户”表单作为局部视图加载到模式对话框中。在该视图中,我使用 MVC 助手 Ajax.BeginForm,指定 InsertionMode.ReplaceWith 并将 UpdateTargetId 设置为表单本身,因此可以提交表单,如果有更多信息,它将返回自身的更新版本并替换自身需要。基本上,AJAX 请求应该返回 HTML。

我应该如何传达此类 AJAX 请求的其他结果,例如当操作完成并且没有 HTML 可返回时(例如,用户已成功创建,因此需要关闭模式对话框)?

我可以使用 HTTP 状态代码或内容类型标头吗?我正在寻找最简洁的方法来完成此任务,同时保持与使用 Microsoft 不显眼的 AJAX 的现有 Ajax.BeginForm 方法的兼容性。也许我需要在 AjaxOptions 中指定一个 OnComplete 处理程序,检查状态代码或内容类型,然后如果操作已完成且没有要返回的 HTML,则取消默认的“ReplaceWith”行为。

我的想法与另一篇帖子的评论相同:“通过检查 HTML 内容中的错误消息而不是仅测试响应代码来测试响应似乎并不实际。” Using Http Status Codes During Form Validation

【问题讨论】:

    标签: jquery ajax asp.net-mvc-5 unobtrusive-validation http-response-codes


    【解决方案1】:

    使用 http 状态码是有问题的。考虑一个基于 AJAX 的搜索引擎。用户在一些随机的垃圾中打孔,没有任何结果。服务器可以通过两种方式返回“无结果”:

    404 - “未找到请求的 url”。这是一个 HTTP 级别的错误,必须将其解释为“搜索引擎脚本不存在”。这正是错误的做法 - 脚本存在,它运行,它根本没有发现任何结果。但是现在浏览器会认为搜索 URL 是错误的。

    200 - OK,并在结果正文中返回搜索状态信息。例如一些 json:{"status":"ok","results":[]}。这是正确的做法。搜索脚本存在,它运行,它成功查询了数据库,它根本没有结果返回给用户。

    在现实世界中,这相当于你的配偶告诉你去商店购买随机物品 X。你开车去商店,商店在那里,它开门了,但只是缺货。在这种情况下。 “404” - 商店不存在。 "200"+json - 商店存在,但没有库存。

    【讨论】:

    • 抱歉,这是不正确的。 404 表示未找到请求的 resource。除了指示正在请求什么资源的 URL 之外,它与 URL 无关。此外,查询字符串是 URL 的一部分,因此可以区分它。对google.com?q=Foo 的请求与google.com?q=Bar 是完全不同的资源。如果“Foo”不存在任何结果,则返回 404 是 100% 合适的,并且与浏览器期望从“Bar”搜索中看到的内容无关。
    • 澄清一下,像谷歌这样的搜索引擎在这种情况下永远不会返回 404,因为这会导致用户界面不好。但是,在 API 之类的情况下,您看到 404,因为它非常合适,并且无需关注 UI。不过,这是网站做出的选择,与 HTTP 状态码的实际含义没有任何关系。
    • 考虑一下。该标准在这里定义了似乎完全符合要求的状态代码,例如 201(已创建)和......“205(重置内容):服务器已完成请求并且用户代理应该重置导致请求的文档视图发送。此响应主要是为了允许通过用户输入进行操作的输入,然后清除给出输入的表单,以便用户可以轻松地启动另一个输入操作。 w3.org/Protocols/rfc2616/rfc2616-sec10.html
    • 资源是资源,在这种情况下是特定术语的搜索结果。如果该术语没有结果,那么它就是 404,简单明了。 HTTP 不知道或关心在另一端是否有某个演员做出该决定(“脚本”)。
    • 对。请参阅我的答案下方的评论。只要你能可靠地使用。很有可能它是一个你应该完全使用的好代码,但是如果你使用的库不理解它,或者浏览器做了一些屏蔽它,或者服务器没有正确发送它,或者其他什么,那么它不再可行。只需做一些测试,如果一切正常,那就去做吧。虽然真正的 API 应该始终返回特定的“正确”代码,但对于您的特定应用程序来说,它实际上并不是那么关键。归根结底,我想说做最有效、最简单的事情。
    【解决方案2】:

    是的,响应代码应该始终指示状态。如果一切都很好,你应该返回 200,无论如何。但是,在这种情况下,仅响应代码对您没有帮助。

    例如,无论是要加载新的 HTML,还是只需要关闭模态框,在任何一种情况下,响应代码都是 200。如果您需要响应的可变性,那么您需要停止使用Ajax 控件。

    总的来说,我不鼓励所有人使用任何Ajax 控件。您可能会轻松获得多少收益,但您会大大失去对正在发生的事情的可见性和控制权。当人们使用这些控件时,他们几乎总是会在此处或其他网站寻求帮助,因为某些东西无法正常工作。

    如果您实现自己的 AJAX,那么您可以返回一个 JSON 对象,这将为您提供无限的灵活性。您可以对任何您喜欢的状态进行编码,如果您愿意,可以包含应该呈现的 HTML。然后,您可以在 AJAX 回调中检查该对象并做出适当的反应,而不是依赖 Microsoft 来决定应该做什么。

    【讨论】:

    • 根本不是这样的。 Ajax.BeginForm 提供了开箱即用的简单性。它的事件处理程序完全反映了 jQuery API,因此我对它的控制与直接调用 jQuery.ajax 一样多。 only 限制是,对于 Ajax.BeginForm,必须将 On* 处理程序指定为全局可访问的函数名称,而不是函数引用。话虽如此,我在问我是否应该设置一个 200(OK)以外的响应代码来指示操作的结果。例如,有 201(已创建)。
    • 事实上,标准中似乎为我的情况定义了另一个响应代码:“205(重置内容)服务器已完成请求,用户代理应重置导致文档视图要发送的请求。此响应的主要目的是允许通过用户输入进行操作的输入,然后清除给出输入的表单,以便用户可以轻松地启动另一个输入操作。”跨度>
    • 您基本上是对的,始终如一地使用 JSON 对象会更容易。但是,我无法忘记协议已经包含我们基本上只是忽略的内容类型和状态。
    • 如果你想走那条路,没关系。以前我实际上并不知道 205,但这并不是因为我已经记住了完整的列表,所以我也可以在任何给定的时刻应用最合适的那个。 (另一个最有可能导致未充分利用的原因:人脑无法假装足够的兴趣将所有代码保存在湿存储中)。无论如何,如果你找到了一个有效的代码并且你可以可靠地使用它,那么我认为这是一个完全可以接受的前进方式。
    猜你喜欢
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    相关资源
    最近更新 更多