javascript - 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
解决方案
您可能需要将客户端的 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 实例上执行的代码,并查看所有设置是否正确。
推荐阅读
- typescript - 有没有办法让 TypeScript 在类型级别区分两个空值?
- angular - 使用Angular 10中的自定义管道获得最低数字
- sql - 如何检索postgres功能索引列名
- angular - 离子启动太慢
- python - 管理员中的 Django 模型返回 TypeError:一元的错误操作数类型 -:'str'
- bash - 为什么部署到 K8s 时找不到 bash 文件?
- airflow - 无法通过 CLI 创建用户
- image - VueJS - 使用来自 API 的 id 时无法显示图像和消息
- java - 将 Map 从 SpringBoot 后端发送到 Angular View 并将其保存在 LocalStorage
- xml - Oracle SQL Developer 隐藏了我的部分 XML 输出