jQuery 是不是有等效的 Request.IsMvcAjaxRequest()?

Posted

技术标签:

【中文标题】jQuery 是不是有等效的 Request.IsMvcAjaxRequest()?【英文标题】:Is there a Request.IsMvcAjaxRequest() equivalent for jQuery?jQuery 是否有等效的 Request.IsMvcAjaxRequest()? 【发布时间】:2010-09-22 07:00:59 【问题描述】:

我更喜欢在我的 ASP.NET MVC 应用程序中使用 jQuery,而不是 Microsoft Ajax 库。我在我的 ajax 调用中设置的操作中添加了一个名为“mode”的参数。如果提供,我返回一个 JsonViewResult。如果没有提供,我假设它是一个标准的 Http 帖子并返回一个 ViewResult。

我希望在使用 jQuery 时能够在我的控制器中使用类似于 IsMvcAjaxRequest 的东西,这样我就可以在我的 Actions 中消除额外的参数。

是否有任何东西可以在我的控制器中提供此功能或一些简单的方法来完成它?我不想疯狂地编写代码,因为添加单个参数是可行的,但这并不理想。

【问题讨论】:

对于任何困惑的人,IsMvcAjaxRequest 现在已重命名(从 RC1 开始)仅为 IsAjaxRequest,只是为了使其与其他 Ajax 库兼容。请看我下面的帖子 【参考方案1】:

这是 MVC RC1 发行说明中的​​一个例外 - 2009 年 1 月

IsMvcAjaxRequest 重命名为 IsAjaxRequest

IsMvcAjaxRequest 方法被 重命名为 IsAjaxRequest。作为...的一部分 这个变化,IsAjaxRequest 方法 已更新以识别 X-Requested-With HTTP 标头。这是 由少校发送的众所周知的标头 javascript 库,例如 Prototype.js、jQuery 和 Dojo。

更新了 ASP.NET AJAX 帮助程序以发送此标头 要求。然而,他们继续 也将其发送到表单的正文中 发布以解决此问题 剥离未知的防火墙 标题。

换句话说 - 它被专门重命名为与其他库更“兼容”。

此外,对于尚未阅读 full release notes 但一直在使用以前版本(甚至是最近的测试版)的任何人,我强烈建议您完整阅读它们。它将为您节省未来的时间,并且很可能会通过一些新功能激发您的兴趣。令人惊讶的是那里有多少新东西。

重要提示:如果从 Beta 升级到 RC1,您需要确保升级 MicrosoftAjax.MVC 的 .js 文件(不是确切名称) - 否则此方法将不起作用.它未在发行说明中列为升级所需的任务,因此请不要忘记。

【讨论】:

谢谢 Simon,希望 Andrew Van Slaars 能给你接受的答案。 另外,将我的帖子更改为社区 wiki,以防其他人想要更新“已接受的答案” 谢谢。我相信我的答案总有一天也会过时 :) 当你写答案时我什至没有听说过 ASP.NET MVC :)【参考方案2】:

请参阅下面的 Simons 回答。我这里描述的方法在最新版本的 ASP.NET MVC 中不再需要了。

IsMvcAjaxRequest 扩展方法目前的工作方式是检查Request["__MVCASYNCPOST"] == "true",并且仅在该方法是 HTTP POST 请求时才有效。

如果您通过 jQuery 发出 HTTP POST 请求,您可以将 __MVCASYNCPOST 值动态插入到您的请求中,然后您可以利用 IsMvcAjaxRequest 扩展方法。

为了您的方便,这里是link to the source of the IsMvcAjaxRequest extension method。

或者,您可以创建 IsMvcAjaxRequest 扩展方法的克隆,称为 IsjQueryAjaxRequest 检查 Request["__JQUERYASYNCPOST"] == "true",您可以将该值动态插入 HTTP POST。

更新

我决定继续尝试,这就是我想出的。

扩展方法

public static class HttpRequestBaseExtensions

    public static bool IsjQueryAjaxRequest(this HttpRequestBase request)
    
        if (request == null)
            throw new ArgumentNullException("request");

        return request["__JQUERYASYNCPOST"] == "true";
    

从操作中检查方法是否为 jQuery $.ajax() 请求:

if (Request.IsjQueryAjaxRequest())
    //some code here

JavaScript

$('form input[type=submit]').click(function(evt) 
    //intercept submit button and use AJAX instead
    evt.preventDefault();

    $.ajax(
        
            type: "POST",
            url: "<%= Url.Action("Create") %>",
            dataType: "json",
            data:  "__JQUERYASYNCPOST": "true" ,
            success: function(data) alert(':)');,
            error: function(res, textStatus, errorThrown) alert(':(');
        
    );
);

【讨论】:

那么当使用“$.post”时,我是否会像在我的帖子数据中传递任何其他参数一样传递__JQUERYASYNCPOST?如果是这样,那将给我相同的基本设置,而无需额外的参数,这将是完美的。 是的,传递 $.post() 的 data 参数中的值。我将首先使用 __MVCASYNCPOST 进行测试,以确保它适用于现有的扩展方法。如果是这样,那么您可以实现自己的扩展方法并将其更改为 __JQUERYASYNCPOST。 再次感谢,我刚刚在我正在处理的项目中实现了代码。如果我在写之前再看这里,我可以做一个复制粘贴:) 请在下面查看我的回答,了解 RC1 的重要变化【参考方案3】:

您为什么不简单地检查大多数 Javascript 库(如 jQuery)自动发送的“X-Requested-With”HTTP 标头?

在发送 GET 或 POST 请求时,它的值为 'XMLHttpRequest'。

为了测试它,您只需要检查您的操作中的“Request.Headers”NameValueCollection,即:

if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
    return Json(...);
else
    return View();

这样,您可以简单地区分常规浏览器请求和 Ajax 请求。

【讨论】:

好主意。我将避免更改我的答案,以便您获得尽可能多的代表:) 我不知道 request-with 标头甚至在那里。我会检查一下并试一试,也许我会更新扩展方法来检查它。知道为什么 MSFT 一开始就不会这样做吗? 实际上,据我所知,该主题缺乏标准化。所有库都以不同的方式构造它们的标头(有些指定库版本),但幸运的是大多数都采用了“X-Requested-With”,我不知道为什么微软没有。 @sork 自从 RC1 以来他们现在就认出了它【参考方案4】:

好的,我已经更进一步,并修改了我的 jQuery 文件以将附加参数加载到发布数据中,因此我不必为每次发布调用重复“__JQUERYASYNCPOST:true”。对于任何感兴趣的人,这是我对 $.post 的新定义:

post: function(url, data, callback, type) 
            var postIdentifier = ;
            if (jQuery.isFunction(data)) 
                callback = data;
                data = ;
            
            else 
                postIdentifier =  __JQUERYASYNCPOST: true ;
                jQuery.extend(data, postIdentifier);
            

            return jQuery.ajax(
                type: "POST",
                url: url,
                data: data,
                success: callback,
                dataType: type
            );
        

我添加了“postIdentifier”变量以及对 jQuery.extend 的调用。现在,spoon16 的响应中解释的 Helper 可以正常工作,而无需向我的页面级 jQuery 代码添加任何特殊内容。

【讨论】:

不错...这是 SO 上最完整的 QA 之一 :) 如果你扩展了'ajax()'呢?像“post()”这样的所有其他方法都只是调用“ajax”,这不是更好吗? 我可以扩展 ajax,但我主要关心的是 post。通常,如果 get 是一个仅 ajax 的特性,我只对 Ajax 使用 get,例如自动完成查找或没有 ajax 就无法使用的类似功能,所以对于这些事情,我还是使用 JsonResult。

以上是关于jQuery 是不是有等效的 Request.IsMvcAjaxRequest()?的主要内容,如果未能解决你的问题,请参考以下文章

Javascript/Coffeescript/jQuery 中是不是有与 Ruby 的发送等效的内容?

jquery load 方法是不是提供与 Rails replace_html 方法等效的 ajax 功能?

JavaScript 等效于 jQuery 的扩展方法

Django request.is_ajax 返回 false

是否有等效的 Javascript 或 Jquery 睡眠功能?

jQuery .load() 等效 AngularJS