【问题标题】:React component has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resourceReact 组件已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头
【发布时间】: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

标签: javascript reactjs asp.net-web-api


【解决方案1】:

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

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

【讨论】:

  • 请提供任何可能的示例或代码 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 来解决它,并在请求中使用它,而不是将其固定在一个或另一个上。

        【讨论】:

          猜你喜欢
          • 2019-12-05
          • 1970-01-01
          • 2020-01-24
          • 2021-12-27
          • 1970-01-01
          • 2020-04-16
          • 2021-04-28
          • 2022-06-21
          • 2022-07-19
          相关资源
          最近更新 更多