访问被 CORS 阻止的 XMLHttpRequest,请求的资源上不存在“Access-Control-Allow-Origin”标头,仅用于 PUT 和 DELETE API

Posted

技术标签:

【中文标题】访问被 CORS 阻止的 XMLHttpRequest,请求的资源上不存在“Access-Control-Allow-Origin”标头,仅用于 PUT 和 DELETE API【英文标题】:Access to XMLHttpRequest blocked by CORS, No 'Access-Control-Allow-Origin' header is present on the requested resource for PUT and DELETE API only 【发布时间】:2021-11-17 08:33:28 【问题描述】:

对于 PUT 和 DELETE 请求,我遇到了低于 CORS 错误,GET 和 POST 请求工作正常:

Access to XMLHttpRequest at 'https://localhost:444/api/...' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

关于我的应用程序的背景:前端在 React(next.js) 中,后端在 .NET 5 中。在后端项目中,我已经设置了 CORS 策略以允许任何标头、方法和特定来源,但现在仍在工作。当我在 IIS Express 上运行 API 项目时,它可以工作,但是当我将它部署到 IIS 时,它失败并出现上述错误。

以下是 .NET 5 项目中的 CORS 策略:

-- public void ConfigureServices(IServiceCollection services)

            services.AddCors(options =>
            
                options.AddDefaultPolicy(
                    builder =>
                    
                        builder
                          .AllowAnyHeader()
                          .AllowAnyMethod()
                          .WithOrigins("http://localhost:3000");
                    );

-- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

app.UseRouting();
app.UseCors();
app.UseAuthorization();

这是 PUT 的 OPTIONS 请求:

**General:**
Request Method: OPTIONS
Status Code: 204 
Remote Address: [::1]:444
Referrer Policy: strict-origin-when-cross-origin
**Response Headers:**
access-control-allow-headers: content-type
access-control-allow-methods: PUT
access-control-allow-origin: *
date: Fri, 24 Sep 2021 01:49:11 GMT
server: Microsoft-IIS/10.0
x-powered-by: ASP.NET

有什么想法吗?

【问题讨论】:

介意发布完整的请求/响应对象吗? 你可以在你的帖子中添加 config xml 文件吗? 【参考方案1】:

问题不在于 CORS 策略,而在于 web.config 中的 WebDAVModule。如果您尝试来自浏览器或 Postman 的 PUTDELETE 请求,您将收到来自 Web 服务器的 405 Not allowed 错误。

我已经从 React 应用程序中尝试了相同的方法。我收到了以下回复。

控制台显示from origin 'http://localhost:9100' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.,但“网络”选项卡显示错误的状态代码为 405。

要解决此问题,您必须在 web.config 中添加以下配置。

     <modules>
        <remove name="WebDAVModule" />
     </modules>
      <handlers>
        <remove name="WebDAV" />
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE,DEBUG" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
      </handlers>

即使我已经从 Startup 类中删除了端口号并为 CORS 添加了以下内容。

          // global cors policy
            app.UseCors(builder => builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .SetIsOriginAllowed((host) => true)
                .AllowCredentials()
            );

请参考.Net核心应用here和React应用沙箱here。

阅读更多关于 405 方法不允许错误here

【讨论】:

【参考方案2】:

我猜你的问题是WebDAVModule 正在禁用 PUT 和 DELETE 方法。您必须在 &lt;handlers&gt; 之前的 web.config 文件中的 &lt;system.webServer&gt; 中包含以下代码块,如下所示:

<modules>
    <remove name="WebDAVModule" />
</modules>
<handlers>
</handlers>

【讨论】:

【参考方案3】:

我相信,当您部署代码时,客户端 url 将从 http://localhost:3000 说 [http://example.com/8080][1] 将此 url 放入 WithOrigins 方法中 -

-- public void ConfigureServices(IServiceCollection services)

        services.AddCors(options =>
        
            options.AddDefaultPolicy(
                builder =>
                
                    builder
                      .AllowAnyHeader()
                      .AllowAnyMethod()
                      ***.WithOrigins("http://example.com/8080");***
                );

【讨论】:

【参考方案4】:

首先您需要更改您正在使用的端口 端口 444 是保留的,因此您需要从端口 3000 开始,操作系统可能会使用前 2000 个端口。端口 444 可以免费使用,如果

***说

简单网络寻呼协议 (SNPP) 是一种协议,它定义了寻呼机可以通过 Internet 接收消息的方法。它受到大多数主要寻呼提供商的支持,并且可以替代许多电信服务使用的寻呼调制解调器。该协议最近在 RFC 1861 中进行了描述。它是一个相当简单的协议,可以在 TCP 端口 444 上运行,并且只使用少数记录良好的命令即可发送页面。

如果你在 yow package.json 有一个 CRA,添加一个新的 prop 调用 proxy 和你返回的 url,如果你添加它,你所有的 cors 问题都会消失

"proxy": "http://localhost:8080"

现在您的所有获取都需要有一个相对 url

而不是

fetch("http://localhost:8080/api/login")

他们必须像

fetch("/api/login")

注意:package.json 中的代理属性如何不以 / 结尾,如果您将其添加到您的包中,它们如何获取以它开头 / '将能够添加饼干和东西。因为如果前后有相同的端口,整个事情就会像这样

【讨论】:

以上是关于访问被 CORS 阻止的 XMLHttpRequest,请求的资源上不存在“Access-Control-Allow-Origin”标头,仅用于 PUT 和 DELETE API的主要内容,如果未能解决你的问题,请参考以下文章

从源 xxxx 访问 XMLHttpRequest ' 被 CORS 策略阻止:对预检的响应。预检请求不允许重定向

Laravel + Angular 从外部网络访问被 CORS 阻止

被 CORS 策略阻止 - 来自 Django 应用程序的 S3 存储桶访问

CloudFormation API Gateway CORS 问题访问 XMLHttpRequest 被阻止

角 POST 请求被 CORS 策略阻止:对预检请求的响应未通过访问控制检查

请求被 CORS 策略阻止