reactjs - 使用 axios 时出现 CORS 授权问题
问题描述
我在开发我的应用程序时偶然发现了一个问题,现在我陷入了困境。我的 Web 应用程序是一个非常简单的界面,用于使用 MERN 堆栈以及 Redux 和 Axios 注册/记录/修改用户。像这样调用 /update 端点时:
export const updateUser = (userData, history) => dispatch => {
let token = localStorage.getItem("jwtToken");
axios.defaults.headers.common["Authorization"] = token;
console.log(token);
axios
.patch('http://localhost:5000/api/users/update', userData, { crossdomain: true })
.then(res => {
history.push("/dashboard");
})
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
但是,我不断收到 cors 授权错误(“CORS OPTIONS 请求中的 CORS 标头“Access-Control-Allow-Headers”中缺少授权令牌”),尽管在上面的代码中您可以清楚地看到我正在明确设置它(我设置它甚至更早一次,就在用户登录之后)。
我以前在登录/注册发布请求时遇到过类似的 CORS 问题,但是当我在后端添加时它们已得到修复:
router.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
在使用登录/注册发布请求调用数据库时,我之前不应该遇到同样的问题吗?分配的令牌不为空,并且在使用 Postman 测试时所有端点都可以正常工作。我已经没有想法该怎么做了。
这是调用组件:
import React, { Component } from "react";
import { Link, withRouter } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { updateUser } from "../actions/authActions";
import { deleteUser } from "../actions/authActions";
import classnames from "classnames";
class DataChange extends Component {
constructor() {
super();
this.state = {
name: "",
email: "",
password: "",
password2: "",
errors: {}
};
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChange = e => {
this.setState({ [e.target.id]: e.target.value });
};
onDeleteClick = e =>{
e.preventDefault();
this.props.deleteUser(this.props.auth.user.id);
}
onSubmit = e => {
e.preventDefault();
const newUser = {
id: this.props.auth.user.id,
name: this.state.name,
email: this.state.email,
password: this.state.password,
password2: this.state.password2
};
console.log(newUser);
this.props.updateUser(newUser, this.props.history);
};
render() {
const { errors } = this.state; return (
<div className="container">
<div className="row">
<div className="col s8 offset-s2">
<Link to="/dashboard" className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to
home
</Link>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Zmień</b> dane
</h4>
</div>
<form noValidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.name}
error={errors.name}
id="name"
type="text"
className={classnames("", {
invalid: errors.name
})}
/>
<label htmlFor="name">Name</label>
<span className="red-text">{errors.name}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("", {
invalid: errors.email
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">{errors.email}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("", {
invalid: errors.password
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">{errors.password}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password2}
error={errors.password2}
id="password2"
type="password"
className={classnames("", {
invalid: errors.password2
})}
/>
<label htmlFor="password2">Confirm Password</label>
<span className="red-text">{errors.password2}</span>
</div>
<div className="col s6" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Wprowadź zmiany
</button>
</div>
<div className="col s6" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
onClick={this.onDeleteClick}
className="btn btn-large waves-effect waves-light hoverable red accent-3"
>
Usuń użytkownika
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
DataChange.propTypes = {
updateUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
const mapDispatchToProps = {
deleteUser,
updateUser,
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(withRouter(DataChange));
解决方案
在快递应用程序中,您需要添加Authorization
到Access-Control-Allow-Headers
. 您也可以使用 * forAccess-Control-Allow-Origin
来摆脱起源问题。
router.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization");
next();
});
推荐阅读
- php - PHP - 如何从数组中输出元素的组合?
- javascript - 网格列表动画
- android - View Binding 是否支持 Adapter 类的视图绑定
- flutter - Flutter 对父级的回调抛出 nosuchmethoderror
- css - 在保持宽度的同时将兄弟姐妹推到视野之外
- postgresql - 如何仅从 Postgres 中的 csv 文件中导入第一行?
- deep-learning - pytorch:model.forward() 会影响训练过程,即使结果不是损失函数的一部分
- javascript - 使用 javascript 删除 cookie 不显示到期日期
- react-native - 在 react-native-web 上录制和播放音频
- r - 在ggplot上绘制与折线图相交的垂直/水平线