【发布时间】:2019-11-13 01:04:54
【问题描述】:
有 2 个 react 组件,都向服务器发送请求(使用 componentDidMount)每个请求查看令牌是否太旧,如果是,则使用 refreshToken 更新它。
问题 - 第一个请求将成功更新令牌,将返回一个新令牌和一个新的 refreshToken。第二个请求将使用旧的 refreshToken 发送到服务器,服务器将产生错误。
解决方案是声明一个全局变量(window.pending)。如果为 false - 我们不更新令牌,如果令牌已更新 - 为其分配一个承诺,等待其完成并应用生成的令牌。
// From component 1
loadClient = async () => {
const token = await this.props.getToken();
// other code
};
// From component 2
loadProject = async () => {
const token = await this.props.getToken();
// other code
};
// НОС
const tokenProviderHOC = WrappedComponent =>
class extends PureComponent<Props> {
request = null;
componentWillUnmount() {
if (this.request !== null) this.request.abort(); //Cancel server request
}
checkToken = userId => async () => {
const { history } = this.props;
// token, refreshToken, expiresIn from localStorage
const token = methods.getToken("token");
const refreshToken = methods.getRefreshToken("refreshToken");
const expiresIn = methods.getExpiresIn("expiresIn");
if (Date.now() >= expiresIn) {
if (window.pending === false) {
console.log("we are first");
let res;
this.request = this._updateToken({ refreshToken, userId });
window.pending = new Promise(async resolve => {
console.log("request start");
res = await this.request.ready(); //ready - start server request
window.pending = false;
console.log("request end", res ? res.token : false);
return res ? resolve(res.token) : resolve(false);
});
}
console.log("Token is already looking");
return window.pending;
}
return token;
};
render() {
const { userId, history, ...props } = this.props;
return <WrappedComponent {...props} getToken={this.checkToken(userId)} />;
}
};
const mapStateToProps = state => ({
userId: userSelectors.getUserInfo(state)?.id || null,
});
export const tokenProvider = compose(
withRouter,
connect(mapStateToProps),
tokenProviderHOC,
);
必须在控制台中显示:
- '我们是第一'
- '请求开始'或'令牌已经在寻找'
- '请求结束'
现在控制台显示:
- '我们是第一'
- '请求开始'
- '令牌已经在寻找'
- '请求结束'
- '我们是第一'
- '请求开始'
- '令牌已经在寻找'
- tokenProvider.js:121 PUT http://site.loc/user/1/send net::ERR_ABORTED 400(错误请求)
// 因为令牌是另一个 - 请求结束错误'
似乎第二个请求正在等待第一个请求,然后再次尝试从服务器中找出令牌并将旧的 refreshToken 传递给它。如何解决问题?
【问题讨论】:
-
我认为你应该把你的 2 个请求放在 HoC 组件中。然后将第二个请求包装在第一个请求中。
-
不明白。怎么样?
-
全部试用 axios ;) stackoverflow.com/questions/43664566/…
标签: reactjs