React 组件已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头

Posted

技术标签:

【中文标题】React 组件已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头【英文标题】:React component has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource 【发布时间】:2020-02-12 15:57:08 【问题描述】:

当我曾经将它作为一个应用程序运行时,我使用 fetch 从我的反应组件调用 Web API,没有问题,但是当我运行应用程序与 API 分开反应时,我收到了 CORS 错误,我的 fetch 调用如下,

    componentDidMount() 
    console.log(clientConfiguration)

    fetch(clientConfiguration['communitiesApi.local'])
        .then((response) => 
            return response.json();                
        )
        .then(data => 
            console.log(data);
            let communitiesFromApi = data.map(community =>  return  value: community, display: community  );
            this.setState( communities: [ value: '', display: 'Select a Community...' ].concat(communitiesFromApi) );    

        ).catch(error => 
            console.log(error);
        );
;

还有我使用 Axios 的 POST 调用,如下所示。

    handleDownload = (e) => 
    e.preventDefault();

    var formData = new FormData();
    formData.append('communityname', this.state.selectedCommunity);
    formData.append('files', JSON.stringify(this.state['checkedFiles']));

    let url = clientConfiguration['filesApi.local'];
    let tempFiles = clientConfiguration['tempFiles.local'];

    axios(
        method: 'post',
        responseType: 'application/zip',
        contentType: 'application/zip',
        url: url,
        data: formData
    )
        .then(res =>        
            var fileName = `$this.state['selectedCommunity'].zip`;
            saveAs(`https://localhost:44352/TempFiles/$res.data`, fileName);
        );
;

这是我的服务器端 api 代码:

        [HttpGet("communityName")]
    public string Get(string communityName)
    
        string rootPath = Configuration.GetValue<string>("ROOT_PATH");
        string communityPath = rootPath + "\\" + communityName;

        string[] files = Directory.GetFiles(communityPath);

        List<string> strippedFiles = new List<string>();
        foreach (string file in files)
        
            strippedFiles.Add(file.Replace(communityPath + "\\", ""));
        

        return JsonConvert.SerializeObject(strippedFiles);
    

    [HttpPost]
    public string Post([FromForm] string communityName, [FromForm] string files) //FileContentResult
    
        var removedInvalidCharsFromFileName = removeInvalidCharsFromFileName(files);
        var tFiles = removedInvalidCharsFromFileName.Split(',');
        string rootPath = Configuration.GetValue<string>("ROOT_PATH");
        string communityPath = rootPath + "\\" + communityName;

        byte[] theZipFile = null;

        using (MemoryStream zipStream = new MemoryStream())
        
            using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
            
                foreach (string attachment in tFiles)
                
                    var zipEntry = zip.CreateEntry(attachment);

                    using (FileStream fileStream = new FileStream(communityPath + "\\" + attachment, FileMode.Open))
                    using (Stream entryStream = zipEntry.Open())
                    
                        fileStream.CopyTo(entryStream);
                    
                
            

            theZipFile = zipStream.ToArray();
        

        ////return File(theZipFile, "application/zip", communityName + ".zip");

        string tempFilesPath = Configuration.GetValue<string>("Temp_Files_Path");

        if (!System.IO.Directory.Exists(tempFilesPath))
            System.IO.Directory.CreateDirectory(tempFilesPath);

        System.IO.File.WriteAllBytes($"tempFilesPath\\communityName.zip", theZipFile);

        //return System.IO.File.ReadAllBytes($"tempFilesPath\\Test.zip");

        //return $"tempFilesPath\\communityName.zip";
        return $"communityName.zip";
    

我收到如下 Get 错误:“CORS 策略已阻止从源 'http://localhost:3000' 获取 'https://localhost:44368/api/communities' 的访问权限:没有 'Access-Control-Allow-Origin' 标头出现在请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。”

【问题讨论】:

您的 API 是否返回 CORS 标头?问题/修复将在服务器端 - 您已经显示了客户端代码:D 【参考方案1】:

您需要修改服务器。你需要

    在服务器端启用 CORS 并 将托管前端的域添加到允许的来源列表中。

【讨论】:

请提供任何可能的示例或代码 sn-p 吗?我也在研究它唯一缺少的一件事 是的,但由于某种原因它仍然无法访问接受 我不确定,这取决于您的后端是用什么语言编写的。您在问题中提到它曾经在同一个站点上,这是否意味着后端是用 NodeJS 写的?不同的语言和框架有不同的方式来处理 CORS 配置。您还可以在您的网络服务器(Apache、nginx 等)中设置您的允许来源列表 没有后端是用 ASP.Net Core 编写的,我确实修复了它,但现在我遇到了另一个问题,我无法下载文件,我想念什么哥们,我的错误是:FileSaver.min.js:34 从源“localhost:3000”访问 XMLHttpRequest 在“localhost:44352/TempFiles/Community-1.zip”已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。 【参考方案2】:

您需要在服务器端添加 cors 这可以通过停止服务器轻松完成,然后

npm install cors

如果您使用多个文件进行路由,则将其添加到主路由器文件中

const express = require("express");
const router = express.Router();
const cors = require("cors");
router.use(cors());

你已经为多文件路由器设置好了。

对于单文件路由器,您应该使用以下代码:

const express = require("express")
const app = express()
const cors = require("cors")

app.use(cors())

你们都准备好了 这应该可以解决错误

【讨论】:

【参考方案3】:

mode: 'no-cors' 添加到 fetch 方法应该可以解决问题

  fetch(clientConfiguration['communitiesApi.local'], 
    mode: 'no-cors'
  )
  .then((response) => 
      return response.json();                
  )
  .then(data => 
      console.log(data);
      let communitiesFromApi = data.map(community =>  return  value: community, display: community  );
      this.setState( communities: [ value: '', display: 'Select a Community...' ].concat(communitiesFromApi) );    

  ).catch(error => 
      console.log(error);
  );

在使用 axios 时,我喜欢使用来自 chrome 网上商店的 Allow CORS: Access-Control-Allow-Origin,在 localhost 上开发 web 应用程序时非常方便

【讨论】:

并非总是这样。在我的情况下,它得到的响应是空的。【参考方案4】:

谢谢你,我可以通过在我的 Web API 上实现 CORS 来解决这个问题,这是我所做的代码,但是在 Web Api 已经实现并且我们需要使用 Api 的情况下,你的代码也很好用不是去修改api的方法,然后你从客户端工作。这是我对 Web API 的更改

public void ConfigureServices(IServiceCollection services)

    string configValue = Configuration.GetValue<string>("CORSComplianceDomains");
    string[] CORSComplianceDomains = configValue.Split("|,|");

    services.AddCors(options =>
    
        options.AddDefaultPolicy(
            builder =>
            

                builder.WithOrigins("http://localhost:3000");
            );

        options.AddPolicy("AnotherPolicy",
            builder =>
            
                builder.WithOrigins(CORSComplianceDomains)
                                    .AllowAnyHeader()
                                    .AllowAnyMethod();
            );

    );

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    // In production, the React files will be served from this directory
    services.AddSpaStaticFiles(configuration =>
    
        configuration.RootPath = "ClientApp/build";
    );

并在 appsettings.json 文件中添加了 url,这样任何用户都可以轻松添加新的 url。

  "CORSComplianceDomains": "http://localhost:3000|,|http://www.contoso.com"

非常感谢 - 我把我的答案放在这里以便有人可以得到它 - 感谢您的参与和帮助 - 我很感激 - 非常感谢。

【讨论】:

【参考方案5】:

那天我在一个 react 项目上遇到了一个非常相似的问题,为了解决这个问题,我必须更改我的 package.json,写成 "proxy": "your origin" 在我的情况下类似于 "proxy": "http ://本地主机:5000”。 希望您能解决您的问题。

【讨论】:

【参考方案6】:

我在浏览器日志中遇到了同样的错误,但我没有使用 React。

原来我是通过 IP 加载我的页面,但我的 javascript 使用服务器域名调用 API。所以浏览器认为这是一个跨站请求并阻止它。如果您收到相同的消息并且互联网搜索引擎将您带到这里,请检查您的情况是否不同。

如果是这种情况,您可以通过找出访问是通过域还是 IP 来解决它,并在请求中使用它,而不是将其固定在一个或另一个上。

【讨论】:

以上是关于React 组件已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头的主要内容,如果未能解决你的问题,请参考以下文章

无法在 React 中使用 GraphQL 查询 - 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头

domain.com 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态

http://localhost:4200' 已被 CORS 策略阻止:对预检请求的响应未通过

已被 CORS 策略阻止:对预检请求的响应未通过

本地主机已被 cors 策略请求标头字段内容类型阻止访问控制不允许

ReactJS:对 fetch 的访问已被 CORS 策略阻止