首页 > 解决方案 > Heroku 请求的资源上不存在“Access-Control-Allow-Origin”标头。使用 React JS 使用 API 时

问题描述

我在这里将我的 express JS API 部署到 Heroku:

https://mylink.herokuapp.com/somefile/do-somestuff

我在 http://localhost:3000 上有我的 React JS 应用程序

当我使用 PostMan 使用 Heroku API 时,它运行良好。但是,当我使用 React JS App 使用它时,我收到以下错误:

localhost/:1 从源“http://localhost:3000”访问“https://mylink.herokuapp.com/somefile/do-somestuff”的 XMLHttpRequest 已被 CORS 策略阻止:否“访问控制允许” -Origin' 标头存在于请求的资源上。mylink.herokuapp.com/somefile/do-somestuff:1 无法加载资源:net::ERR_FAILED

这是我的 Express JS API:

const express = require('express');
const app = express();
const myRouter = require('./someFile');
const cors = require('cors');


app.listen(process.env.PORT, () =>{
    console.log(`App is listening on port 5000`);
});

app.use(cors(/**{
    origin: `http://localhost:3000`,  //react's address
    credentials: true
}*/));


app.use(express.json());

app.use('/somefile', someFile);

app.get('/', (request, response) =>{
    response.send('Homepage');
});



module.exports = app;

在 someFile.js 中:

const express = require('express');
const app = express();

const router = express.Router();



router.post('/do-somestuff', async (request, response) =>{
   
        let token = request.body.passedtoken;
        
        let latestOTP = await otpCodeModel.find({someField:token}).sort({_id: -1}).limit(1); 
        
        return response.json({message: latestOTP});
         
});


module.exports = router;

这是我的反应代码:

class App extends React.Component{

    constructor(props){
        super(props);
    }
    
    
    sendPassedToken = (token) => {
            axios.post(`https://mylink.herokuapp.com/somefile/do-somestuff`, token)
                .then((response) => {
                    console.log(response.data.message);
                }).catch((error) => {
                console.log(error);
            });
            
            console.log(token);
    }
}


export default App;

有什么问题,为什么它不工作并且在使用 React JS 中的 heroku api 时总是抛出以下错误:

localhost/:1 从源“http://localhost:3000”访问“https://mylink.herokuapp.com/somefile/do-somestuff”的 XMLHttpRequest 已被 CORS 策略阻止:否“访问控制允许” -Origin' 标头存在于请求的资源上。mylink.herokuapp.com/somefile/do-somestuff:1 无法加载资源:net::ERR_FAILED

标签: javascriptnode.jsreactjsexpressheroku

解决方案


您可能需要将客户端的 axios 请求标头修改为 setwithCredentials: true和/或credentials: 'include'.

反应代码:

class App extends React.Component{   
   constructor(props){
     super(props);
   }
    
   sendPassedToken = (token) => {
     axios
      .post(
       `https://mylink.herokuapp.com/somefile/do-somestuff`,
        token, 
        { withCredentials: true } //credentials: 'include' -- for fetch
       )
       .then((response) => {
         console.log(response.data.message);
       }).catch((error) => {
           console.log(error);
       });
            
       console.log(token);
    }
}

export default App;

我知道您可能已经知道这一点,但请确保在运行后端时取消注释。似乎设置得很好:

app.use(cors({
    origin: `http://localhost:3000`,  //react's address
    credentials: true
}));

编辑:我收到了你的通知,但我猜你删除了评论。请记住,如果您尚未在其他地方设置 axios 请求对象的标头,则可能必须通过 cors 飞行前请求。我相信您不必添加credentials: 'include'到 axios 请求(可能用于获取),但您需要withCredentials: true为 axios 添加,除非您已在其他地方的 axios 对象本身上设置它。这种类型的 cors 设置要求您指定原点而不是“*”,因为您正在设置credentials:true,您正在后端执行此操作。

因此,如果您在浏览器开发工具中检查来自网络选项卡的请求,并且您会得到某些信息,例如——

A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:3000' is therefore not allowed access.

然后该路由、应用程序或 cors 模块设置不正确。也许您忘记取消注释您发送到 cors 模块的 headers 对象?如果您为 Heroku 设置源代码管道,请检查该分支中的文件,因为它将是在该 Heroku 实例上执行的代码,并查看所有设置是否正确。


推荐阅读