这里仅以flyio与fetch-jsonp结合作为示例(token存放在cookie中),具体代码逻辑视项目而定
要点
- flyio拦截器中执行异步任务
- 发送jsonp请求
现在有两个不同域网站 a网站 & b网站
1. 当访问a网站时检测有无token,无token则向b网站发送jsonp请求换取token,在token请求回来之前暂不受理其他任何请求(防止重复发送jsonp请求),获取后将token写入cookie,写入完毕后,跳转到b网站进行登录,有token则进行下一步。
2. 已有token,a网站的响应拦截器则检测token是否过期,未过期则放行,过期则向b网站发送jsonp请求更新token,更新成功刷新页面。
主要代码
import React from 'react';
import {Router, Route} from 'react-router-dom';
import fly from 'flyio';
import Cookies from 'js-cookie';
import fetchJsonp from 'fetch-jsonp';
fly.config.withCredentials = true;
fly.config.baseURL = "/";
class Root extends React.Component {
componentWillMount() {
let _this = this;
fly.interceptors.request.use(function (request) {
if (!Cookies.get('token')) {
//锁定当前实例,后续请求会在拦截器外排队,防止重复请求,当前请求也会等待jsonp的执行完毕
fly.lock();
return _this.handleRequestJsonp(request);
} else {
request.headers["token"] = Cookies.get('token');
return request;
}
});
fly.interceptors.response.use(
function (response) {
if (response.headers['isTokenValid'] === '0') {
this.lock(); //无效,锁定响应拦截器,防止重复jsonp请求
_this.handleResponseJsonp(this, response);
} else {
return response;
}
},
function (error) {
_this.handleError(error);
return Promise.reject(error);
}
);
}
handleRequestJsonp = (request) => {
// fetchJsonp中的请求url必须以(.jsonp)结尾
fetchJsonp(`b网站接口地址.jsonp`).then(function(response) {
return response.json();
}).then(function(json) {
Cookies.set('token', json.token);
// 可能会根据其他条件判断是否需要跳转到登录页面,如无需跳转则返回request,则会继续发送原来的请求,如要继续发送原来的请求 需要加入 request.headers['token'] = json.token;,这里简单处理直接跳转到登录页面
window.location.href = 'b网站登录页面地址';
}).catch(function(ex) {
console.log(ex);
}).finally(() => {
fly.unlock(); // 解封当前实例,后续请求队列依次发送
});
};
handleResponseJsonp = (that, response) => {
fetchJsonp(`b网站更新token接口地址.jsonp`).then(function(result) {
return result.json();
}).then(function(json) {
Cookies.remove('token');
Cookies.set('token', json.token);
}).finally(() => {
return that.unlock();
}).then(() => {
window.location.reload(); // 刷新页面,这里也可以重发当前请求,具体见flyio官网
}).catch(function(ex) {
console.log(ex);
});
};
render() {
return (
<div>Root</div>
)
}
}
export default Root;