'访问控制允许来源'从React(Isomorphic应用程序)进行API调用时出现问题

时间:2017-01-06 01:48:17

标签: javascript node.js reactjs isomorphic-javascript axios

我使用React和Express遇到了我的同构JavaScript应用程序的问题。

当我的组件安装

时,我正在尝试使用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
  })
}

我从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.

但是,如果我在server.js中发出请求

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

它工作正常,我在服务器启动时获得响应数据。这是实际API的问题还是我做错了什么?如果这是一个CORS问题,我猜测server.js中的请求也不会起作用?谢谢!

14 个答案:

答案 0 :(得分:16)

使用名为Allow-Control-Allow-Origin: *的Google Chrome扩展程序。它会在您的应用程序中动态修改CORS标头。

答案 1 :(得分:15)

CORS是浏览器功能。服务器需要选择加入CORS以允许浏览器绕过同源策略。您的服务器不会受到相同的限制,并且能够使用公共API向任何服务器发出请求。 https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

在服务器上创建一个端点,启用CORS,可以充当您的Web应用程序的代理。

答案 2 :(得分:6)

修复而不使用外部代理或Chrome扩展程序

CORS应该在服务器端启用!如果您无法在服务器上激活它(例如使用外部API),请创建一个中间件React -> Middleware -> Orginal Server

  1. 创建一个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);
    

这会将请求http://localhost:5000/api/xxx传递到原始服务器(例如http://localhost:8080/api/xxx),并将结果返回给客户端。

  1. 更改客户端(反应)以调用代理并获取没有CORS错误的数据:

    axios.get('http://localhost:5000/api/xxx', //proxy uri
    {
       headers: {
          authorization: ' xxxxxxxxxx' ,
          'Content-Type': 'application/json'
       } 
    }).then(function (response) {
       console.log(response);
    });
    
  2. 运行节点项目node app.js并对项目npm start做出反应。

答案 3 :(得分:2)

我认为您的问题的答案是here

  

要让Chrome在标头中发送Access-Control-Allow-Origin,只需将/ etc / hosts文件中的localhost别名替换为其他域,例如:

     

127.0.0.1 localhost yourdomain.com

答案 4 :(得分:2)

在调试模式下使用vs代码时,可以使用此代码。

“ 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/"
      ]
    }
  ]
}

或直接运行

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

答案 5 :(得分:1)

我在fetch命令中遇到了同样的问题。快速浏览here中的文档,就会发现:

如果您请求的服务器不支持CORS,您应该在控制台中收到一条错误消息,表明由于缺少CORS Access-Control-Allow-Origin标头而导致跨域请求被阻止。

您可以使用无心模式来请求不透明资源。

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

答案 6 :(得分:1)

        //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

答案 7 :(得分:1)

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

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

答案 8 :(得分:0)

由于服务器没有CORS标头,因此您无法获得响应。

这是我从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

响应标头中没有CORS标头。

答案 9 :(得分:0)

我不知道这是否有帮助,但是在远程调试本机应用程序时出现相同的错误。我在 192.168.x.x:8081 上运行调试器。我在此Cross-Origin Resource Sharing (CORS)上读了一点,以使自己了解CORS是什么。 (我是初学者),并将我的URL从 IP:8081 更改为 localhost:8081 ,我的问题已解决。

答案 10 :(得分:0)

我有同样的问题。其他答案是正确的,但还有另一种解决方案。 您可以设置响应标头以允许跨域访问。 根据{{​​3}},您必须在任何app.get调用之前添加以下代码:

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

这对我有用:)

答案 11 :(得分:0)

今天,在使用带有Typescript的React和使用Java Spring boot的后端时,我也遇到了同样的错误,如果您有帮助,您可以简单地为CORS添加一个配置文件。

在下面的示例中,我将允许的来源设置为*以允许所有,但您可以更具体,仅设置http://localhost:3000之类的网址。

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;
    }
}

答案 12 :(得分:0)

就我而言,即使在服务器端启用它后,我仍然收到 CORS 错误。问题是网址。 localhost:4001/todos 我忘了在前面加上“http”。

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

您不必在客户端处理它。只需要以下步骤:

第 1 步:

npm install cors

第 2 步:

//express-server.js  

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

完成!

答案 13 :(得分:0)

当您尝试通过 React 应用程序调用端点时,这是一个常见问题,因为 React 应用程序运行在 localhost:3000 上,而 API 位于不同的服务器上。

要纠正此错误,请安装“http-proxy-middleware”

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

安装后在 src 文件夹中创建一个 setupProxy.js

并按照以下代码

    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,
        })
      );
      
    };

您可以在 app.use 中添加任意数量的 api。 然后正常调用api

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

欲了解更多详情,请查看以下链接 Porxying API requests in Development in React JS