【问题标题】:Why do I get CORS errors running this PATCH method from React to WebAPI?为什么从 React 到 WebAPI 运行此 PATCH 方法时会出现 CORS 错误?
【发布时间】:2020-11-06 18:25:11
【问题描述】:

这是我的 Cors 初始化代码:

        app.UseCors(builder =>
            builder.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin());

然而,当我运行 PATCH 时,我在 Chrome 83 中收到以下错误:

CORS 政策已阻止从源“https://users-dev.myproject.com”获取“https://api-dev.myproject.com/api/mp”的访问权限:无“访问权限-请求的资源上存在 Control-Allow-Origin' 标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

这是调用 api 的代码(来自 React):

  const response = await fetch(API_URL() + `/mp`, {
    method: 'PATCH',
    body: `"${JSON.stringify(mpForm.values)}"`,
    headers: {
      Authorization: 'Bearer ' + apiToken,
      'Content-type': 'application/json'
    }
  });

这里可能出了什么问题?对这个域的大多数 API 请求都很好。目前只有这个。

更新

万一您遇到这个确切的问题,这个问题的根本原因是身体线条:

body: `"${JSON.stringify(mpForm.values)}"`,

通过重构 API 以使用这样的主体来解决问题:

body: JSON.stringify(mpForm.values),

这是一个问题的原因是 stringify 函数在返回值中嵌入了双引号,导致传递这样的字符串:

'"{"foo":"bar"}"'

然后导致 CORS 错误。

【问题讨论】:

  • 显示此请求的 Chrome 跟踪,以及对相同 API 的类似请求的跟踪。我们想查看标头和失败并导致退回的特定请求。
  • 查看 OPTIONS 请求的响应,寻找与您的呼叫站点匹配的允许来源。如果不存在,请在您的 API 中查找其他冲突配置
  • 请更新标签以反映这是 ASP.Net 还是核心?
  • @ChrisSchaller 感谢您的提问。现在已经解决了,所以很遗憾我无法重现这些痕迹。但是,问题是由于请求中的正文格式不正确。

标签: c# asp.net-core webapi


【解决方案1】:

您的 CORS 配置看起来是正确的,如果某些请求有效,但其他请求无效,那么问题可能根本不在 API 端。

  1. 在 API startup.cs 中,确保在所有其他配置之前配置 CORS。

    app.UseCors(builder => builder
       .AllowAnyOrigin()
       .AllowAnyMethod()
       .AllowAnyHeader()
    

    此代码是有效的,虽然不是很安全,但它将满足您应用的全局浏览器 CORS 协议

  2. 确保在整个 API 中没有冲突的 CORS 配置,在控制器或方法上查找失败的请求的单个 CORS 配置。

  3. 检查客户端,虽然您的客户端代码看起来OK,但主体是从变量中注入的,要解决任何客户端到服务器问题,您需要以纯文本形式记录完整请求,或者在运行时从 Web 浏览器中的网络流量检查工具中检索它。

    如果对您的 API 的大多数查询都正确解决,并且只有一两个失败,这很好地表明客户端存在问题,您应该从这里开始。


更新:

OP 的问题根本与 CORS 没有直接关系,但它很好地提醒了两个重要的教训:

  1. 格式错误的请求 Web API 在生成对 OPTIONS 请求的正确响应之前可能会失败,如果 OPTIONS 请求没有按照规范响应,浏览器将首先将此报告为 CORS 拒绝问题,抑制来自 API 的真正错误响应

  2. 在向论坛发布问题以寻求解决错误的建议时,提供导致错误的代码只是描绘了部分情况。您需要包含显示运行时值以及实际错误消息的日志。

  • 为了调试客户端和服务器之间的任何 Web API 问题,您应该始终查看实际的 HTTP 请求和响应内容以及受影响调用的标头,您可以使用浏览器开发人员查看网络 trace工具,但是,如果您需要在生产环境中定期调试此类问题,则应考虑在客户端或服务器端进行请求跟踪日志记录。

【讨论】:

  • 我不相信这会起作用,因为您不应该将 AllowAnyOrigin 与 AllowCredentials 结合使用。
  • 感谢@dylanT,您不应该这样做,但这并不意味着您不能。我忽略的关键是它仅在一个特定请求上失败。我假设这是您使用身份验证的唯一请求,但这是一个愚蠢的假设。我现在完全改变了我的回答,但很高兴记住这是 web api 和客户端开发中的常见场景。不要仅仅因为浏览器认为是问题而将CORS视为问题。
  • 感谢您的详细更新。我会将您的答案标记为正确,因为它有一些有用的提示。
【解决方案2】:

您不能将“允许任何来源”与授权结合使用。这是一个安全风险。您可以回显请求的来源,而不是允许任何来源,但您应该知道这样做会带来一些安全风险 - 您允许来自任何域的身份验证令牌。最好使用允许的域正确配置 CORS。

请参阅此问题的公认答案:C# WEB API CORS does not work,了解在这种情况下配置后端的一种方法,避免使用Access-Control-Allow-Origin:*

【讨论】:

  • 我很感激。我只是想让它在最简单的情况下工作。您认为允许任何来源是导致错误的原因吗?
  • 这根本没有解决 OP 的问题
  • @dylanT 是的。我不只是告诉你安全风险。我是说浏览器不允许这样做。
  • @ChrisSchaller ?浏览器将不允许具有允许任何来源的凭据请求。
  • @seesharper 在代码中我们说“允许任何”,但运行时的实现实际上返回调用者主机,而不是“*”,只要没有任何冲突,OP 代码应该正确执行此操作配置
【解决方案3】:

经过多次故障排除后,我们能够确定问题的根本原因是请求的正文。 stringify 方法将双引号嵌入到用双引号括起来的字符串中。

我还不清楚为什么这会导致 CORS 错误,但这很可能是一个红鲱鱼。

修复主体解决了问题。

我有兴趣了解导致浏览器出现 CORS 错误的事件链。但除此之外,我们现在已经解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2020-12-15
    相关资源
    最近更新 更多