为啥我的 ASP.NET MVC 站点中的此 AJAX 请求会触发预检检查?

Posted

技术标签:

【中文标题】为啥我的 ASP.NET MVC 站点中的此 AJAX 请求会触发预检检查?【英文标题】:Why is this AJAX request in my ASP.NET MVC site triggering a preflight check?为什么我的 ASP.NET MVC 站点中的此 AJAX 请求会触发预检检查? 【发布时间】:2017-10-09 17:55:38 【问题描述】:

我有一个 ASP.NET MVC 5 项目,其中一个页面有一些 javascript 调用运行 ASP.NET WebApi 项目的服务器上的 API。这两个项目通常在不同的域上运行,但在本地它们只是在localhost 上的不同端口上。此 JavaScript 正在发出 GET 请求,但是当我查看网络日志时,正在发出 OPTIONS 请求,而 WebApi 返回 405 Method Not Authorized

根据我的研究,我知道this is a "preflight" check that is sometimes triggered for AJAX calls,我知道ASP.NET WebApi doesn't support OPTIONS by default,所以这就是我得到405 的原因。但是,the preflight check is supposed to be skipped when certain conditions are met,并且这些条件在这里得到了满足。你自己看;以下是 AJAX 请求的(匿名的)完整的 JS 代码:

var xmlhttp = new XMLHttpRequest();
var url = "http://localhost:12345/api/SomeAction?someArg=" + someArg;

xmlhttp.onreadystatechange = function () 
  if (xmlhttp.readyState === 4 && xmlhttp.status === 200) 
    // [snip], process the result here
  
;

xmlhttp.open("GET", url, true);
xmlhttp.send();

为什么这个简单的请求会触发预检?

【问题讨论】:

【参考方案1】:

问题是由于 Application Insights 在 MVC 项目中加载了一些额外的 JavaScript。

我通过调试器进入xmlhttp.send() 调用发现了这一点,我最终注意到我在ai.0.js 中。 AppInsights 中的该文件会覆盖 XMLHttpRequest 和 adds a couple custom headers to the request 的定义,这会导致需要进行预检。

因此有两种可能的解决方案:

    禁用 Application Insights 并删除其自定义 JavaScript。 在 API 项目中实现OPTIONS 处理。

Supporting OPTIONS is likely the better solution,所以我最终可能会这样做,但删除 AppInsights 更快,所以我现在就这样做。我在_Layout.cshtml 视图中删除了以var appInsights = window.appInsights... 开头的<script> 标记,从而解决了问题。

【讨论】:

您还应该将此作为问题发布在 AI javascript sdk github.com/Microsoft/ApplicationInsights-JS/issues 上。我不知道为什么 AI 的存在会迫使浏览器进行 CORS 检查。 @JohnGardner:我没有在那里发布问题,因为我认为这不一定是一个错误,只是一个不幸的副作用。我相信 AI 添加的自定义标头会强制进行预检(请参阅我在答案中链接到的 GitHub 上的文件)。如果您认为这实际上是一个错误,请告诉我,我可以提出一个问题。

以上是关于为啥我的 ASP.NET MVC 站点中的此 AJAX 请求会触发预检检查?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法让 Asp.net 零公共站点(Asp.net MVC)中的实时登录用户?

ASP.NET MVC 中的项目布局和站点结构

为啥我的 Jquery Ajax 调用不起作用?(Asp.net MVC C#)

为啥我升级到 MVC3 后我的自定义 HtmlHelpers 停止工作?

为啥 Bootstrap 不允许我在 ASP.NET MVC 页面中的下拉菜单上设置边距?

样式不适用于 ASP.NET MVC 站点