简体   繁体   English

当从 React(同构应用程序)发出 API 调用时出现“Access-Control-Allow-Origin”问题

[英]'Access-Control-Allow-Origin' issue when API call made from React (Isomorphic app)

I'm running into an issue with my isomorphic JavaScript app using React and Express.我在使用 React 和 Express 的同构 JavaScript 应用程序时遇到问题。

I am trying to make an HTTP request with axios.get when my component mounts当我的组件安装时,我正在尝试使用 axios.get 发出 HTTP 请求

componentDidMount() {
  const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
  axios.get(url).then( res => {
    //use res to update current state
  })
}

I am getting a status 200 res from the API, but I am not getting any response data and getting an error in my console我从 API 获得状态 200 res,但我没有获得任何响应数据并且在我的控制台中出现错误

XMLHttpRequest cannot load http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders. 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:3000' is therefore not allowed access.

However, if I make the request in my server.js但是,如果我在我的 server.js 中发出请求

const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
axios.get(url).then(res => {
    //console.log(res);
});

It works fine and I get response data when the server starts.它工作正常,我在服务器启动时获得响应数据。 Is this an issue with the actual API or am I doing something wrong?这是实际 API 的问题还是我做错了什么? If this was a CORS issue I'm guessing the request in server.js wouldn't work either?如果这是一个 CORS 问题,我猜 server.js 中的请求也不起作用? Thanks!谢谢!

CORS is a browser feature. CORS 是浏览器功能。 Servers need to opt into CORS to allow browsers to bypass same-origin policy.服务器需要选择加入 CORS 以允许浏览器绕过同源策略。 Your server would not have that same restriction and be able to make requests to any server with a public API.您的服务器不会有同样的限制,并且能够向任何具有公共 API 的服务器发出请求。 https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Create an endpoint on your server with CORS enabled that can act as a proxy for your web app.在您的服务器上创建一个启用 CORS 的端点,该端点可以充当您的 Web 应用程序的代理。

Use the google Chrome Extension called Allow-Control-Allow-Origin: * .使用名为Allow-Control-Allow-Origin: *的谷歌 Chrome 扩展程序。 It modifies the CORS headers on the fly in your application.它会在您的应用程序中动态修改 CORS 标头。

Fix Without Using External Proxy or Chrome Extension在不使用外部代理或 Chrome 扩展程序的情况下修复

CORS should be enable in server side!应该在服务器端启用 CORS! if you can not activate it on server (for example using external API) create a middleware React -> Middleware -> Orginal Server .如果您无法在服务器上激活它(例如使用外部 API),请创建一个中间件React -> Middleware -> Orginal Server

  1. Create a Node.js project (Middleware) and use below code in app.js .创建一个 Node.js 项目(中间件)并在app.js使用以下代码。

     const express = require("express"); var cors = require('cors') const app = express(); app.use(cors()); const { createProxyMiddleware } = require('http-proxy-middleware'); app.use('/api', createProxyMiddleware({ target: 'http://localhost:8080/', //original url changeOrigin: true, //secure: false, onProxyRes: function (proxyRes, req, res) { proxyRes.headers['Access-Control-Allow-Origin'] = '*'; } })); app.listen(5000);

This will pass the request http://localhost:5000/api/xxx to original server (for example http://localhost:8080/api/xxx ), and returns the result to client.这会将请求http://localhost:5000/api/xxx传递给原始服务器(例如http://localhost:8080/api/xxx ),并将结果返回给客户端。

  1. Change client (React) to call proxy and get data without CORS error (you only need to change the port in url):更改客户端(React)调用代理获取数据,不会出现CORS错误(只需更改url中的端口即可):

     axios.get('http://localhost:5000/api/xxx', //proxy uri { headers: { authorization: ' xxxxxxxxxx' , 'Content-Type': 'application/json' } }).then(function (response) { console.log(response); });
  2. run node project node app.js and react project npm start .运行 node project node app.js和 react project npm start

I had the same problem.我有同样的问题。 the other answers are correct but there is another solution.其他答案是正确的,但还有另一种解决方案。 you can set response header to allow cross-origin access.您可以设置响应头以允许跨域访问。 according to this post you have to add the following codes before any app.get call:根据这篇文章,您必须在任何 app.get 调用之前添加以下代码:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
  });

this worked for me :)这对我有用:)

        //install cors using terminal/command  
        $ npm install cors

        //If your using express in your node server just add
        var cors = require('cors');
        app.use(cors())


       //and re-run the server, your problem is rectified][1]][1]
       **If you won't be understood then see below image**

https://i.stack.imgur.com/Qeqmc.png https://i.stack.imgur.com/Qeqmc.png

You can use this code when using vs code on debugging mode.在调试模式下使用 vs 代码时,您可以使用此代码。

"runtimeArgs": ["--disable-web-security","--user-data-dir=~/ChromeUserData/"] "runtimeArgs": ["--disable-web-security","--user-data-dir=~/ChromeUserData/"]

launch.json启动文件

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Chrome disable-web-security",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}",
      "runtimeArgs": [
        "--disable-web-security",
        "--user-data-dir=~/ChromeUserData/"
      ]
    }
  ]
}

Or directly run或者直接运行

Chrome --disable-web-security --user-data-dir=~/ChromeUserData/

I think the answer for your question is here我想你的问题的答案在这里

To have Chrome send Access-Control-Allow-Origin in the header, just alias your localhost in your /etc/hosts file to some other domain, like:要让 Chrome 在标头中发送 Access-Control-Allow-Origin,只需将 /etc/hosts 文件中的 localhost 别名为其他域,例如:

127.0.0.1 localhost yourdomain.com 127.0.0.1 本地主机 yourdomain.com

I was having the same problem with the fetch command.我在使用fetch命令时遇到了同样的问题。 A quick look at the docs from here tells us this:快速浏览一下这里的文档告诉我们:

If the server you are requesting from doesn't support CORS, you should get an error in the console indicating that the cross-origin request is blocked due to the CORS Access-Control-Allow-Origin header being missing.如果您请求的服务器不支持 CORS,您应该在控制台中收到一条错误消息,表明由于缺少 CORS Access-Control-Allow-Origin 标头,跨域请求被阻止。

You can use no-cors mode to request opaque resources.您可以使用 no-cors 模式来请求不透明的资源。

fetch('https://bar.com/data.json', {
  mode: 'no-cors' // 'cors' by default
})
.then(function(response) {
  // Do something with response
});

I faced the same error today, using React with Typescript and a back-end using Java Spring boot, if you have a hand on your back-end you can simply add a configuration file for the CORS.我今天遇到了同样的错误,使用 React 和 Typescript,后端使用 Java Spring boot,如果你有后端,你可以简单地为 CORS 添加配置文件。

For the below example I set allowed origin to * to allow all but you can be more specific and only set url like http://localhost:3000 .对于下面的示例,我将 allowed origin 设置为 * 以允许所有但您可以更具体并且只设置像http://localhost:3000这样的 url 。

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class AppCorsConfiguration {
    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }
}

Create-React-App 有一个简单的方法来处理这个问题:在 package.json 文件中添加一个代理字段,如下图

"proxy": "http://localhost:8081",

Because the server don't have CORS header, so you are not allowed to get the response.由于服务器没有 CORS 标头,因此您无法获得响应。

This is header from API that I captured from Chrome brower:这是我从 Chrome 浏览器中捕获的 API 标头:

Age:28
Cache-Control:max-age=3600, public
Connection:keep-alive
Date:Fri, 06 Jan 2017 02:05:33 GMT
ETag:"18303ae5d3714f8f1fbcb2c8e6499190"
Server:Cowboy
Status:200 OK
Via:1.1 vegur, 1.1 e01a35c1b8f382e5c0a399f1741255fd.cloudfront.net (CloudFront)
X-Amz-Cf-Id:GH6w6y_P5ht7AqAD3SnlK39EJ0PpnignqSI3o5Fsbi9PKHEFNMA0yw==
X-Cache:Hit from cloudfront
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:b971e55f-b43d-43ce-8d4f-aa9d39830629
X-Runtime:0.014042
X-Ua-Compatible:chrome=1
X-Xss-Protection:1; mode=block

No CORS header in response headers.响应标头中没有 CORS 标头。

I don't know if this will help but I was getting the same error when remote debugging a react-native application.我不知道这是否有帮助,但是在远程调试 react-native 应用程序时我遇到了同样的错误。 I was running the debugger on 192.168.xx:8081 .我在192.168.xx:8081上运行调试器。 I read a little bit on this Cross-Origin Resource Sharing (CORS) to educate myself on what CORS is.我阅读了一些关于跨域资源共享 (CORS) 的内容,以了解 CORS 是什么。 (I'm a beginner) and changed my URL from IP:8081 to localhost:8081 and my issue was resolved. (我是初学者)并将我的 URL 从IP:8081更改为localhost:8081 ,我的问题就解决了。

In my case I was getting the CORS error even after enabling it on server side.就我而言,即使在服务器端启用它后,我仍然收到 CORS 错误。 The issue was url.问题是网址。 localhost:4001/todos I forgot to prepend the 'http'. localhost:4001/todos我忘了在前面加上“http”。

http://localhost:4001/todos //correct way

You don't have to deal with it on client side.您不必在客户端处理它。 Just need the following steps:只需要以下步骤:

Step 1:第1步:

npm install cors

Step 2:第2步:

//express-server.js  

...
const cors = require('cors');
app.use(cors());

Done!完毕!

This is a common issue occurs when you try to call an endpoint via your react app because react app is running on localhost:3000 and apis are on different servers.当您尝试通过 React 应用程序调用端点时,这是一个常见问题,因为 React 应用程序在 localhost:3000 上运行并且 apis 在不同的服务器上。

to rectify this error install 'http-proxy-middleware'要纠正此错误,请安装“http-proxy-middleware”

npm i http-proxy-middleware 
or
yarn add http-proxy-middleware

after installation create a setupProxy.js in your src folder安装后在你的src文件夹中创建一个setupProxy.js

and follow below code并按照以下代码

    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    module.exports = function(app) {
    
        app.use(
        '/getDetails', //this is your api
        createProxyMiddleware({
          target:'http://10.0.0.20:9000/getDetails', //this is your whole endpoint link
          changeOrigin: true,
        })
      );


    app.use(
        '/getproducts', //this is your api
        createProxyMiddleware({
          target:'http://10.0.0.20:9000/getproducts', //this is your whole endpoint link
          changeOrigin: true,
        })
      );
      
    };

you can add as many api as you want in app.use.您可以在 app.use 中添加任意数量的 api。 and then just normally call the api然后只是正常调用api

axios.get('http://10.0.0.20:9680/getDetails')

for more details check below link Porxying API requests in Development in React JS有关更多详细信息,请查看下面的链接Porxying API requests in Development in React JS

Add proxy to package.json file and keep the remaining part of url in the fetch itself.将代理添加到 package.json 文件并将 url 的其余部分保留在 fetch 本身中。

eg.,例如。,

In package.json file, "proxy" : "https://www.google.com", //add your own website link在 package.json 文件中,"proxy" : "https://www.google.com", //添加自己的网站链接

In App.js file const response = await fetch(./...(as per your own))在 App.js 文件中 const response = await fetch(./...(as per your own))

use below after private property in package.json.在 package.json 中的私有财产之后使用下面。

"proxy": "http://localhost:5000", "代理": "http://localhost:5000",

Key is proxy and value is your server url键是代理,值是您的服务器 url

AND other thing is Chrome does not support localhost to go through the Access-Control-Allow-Origin chrome isse cors其他事情是 Chrome 不支持通过 Access-Control-Allow-Origin chrome isse cors访问 go 的 localhost

OR或者

If you use Express please add routes after use cors如果您使用快递请在使用后添加路线 cors

app.use(cors()); app.use(cors());
app.use('/posts', postRoutes); app.use('/posts', postRoutes);

add this to your server.js in your express app将此添加到您的 Express 应用程序中的server.js

const cors=require("cors");
 const corsOptions ={
       origin:'*', 
       credentials:true, //access-control-allow-credentials:true
        optionSuccessStatus:200,
 }

 app.use(cors(corsOptions)) 

make sure to run npm install cors确保运行npm install cors

I fixed the same problem by simply installing "cors" in my server folder.我通过简单地在我的服务器文件夹中安装“cors”来解决同样的问题。 I used express to create an api and tried to send get request to the api but it did not work without "cors".我使用 express 创建了一个 api 并尝试向 api 发送获取请求,但没有“cors”它就无法工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM