前言
每个项目中token都是很重要的一环,如果我们在进行混合开发时候,怎样进行token管理呢。如果遇到那种实时刷新token(每访问一个接口返回一个新的token,别问我,JAVA就是这么叼)该情况怎么处理呢,经过和原生老哥们的讨论和折腾我们有了自己的方案,下面简单说下思路供大家参考!
原生帮我发请求
在做混合开发时,原生一般是封装很多方法供H5使用,比如拍照,定位,录音等等,原生和H5都是分开开发,各种有自己封装的请求,比如IOS AFnetworking ,H5 axios和fetch,虽然各自都可以管理自己的token,信息。如果出现上面那张情况,每访问一个接口返回一个新的token,这个时候怎么处理呢。你可能会说,H5和原生不是可以进行传值吗,每次带过去就可以了。想想很美好,现实很蛋疼。比如有以下场景:
这种情况原生可能要骂人了,交互复杂不说,原生 前端都得管理。动不动还会出现token没有实时刷新的问题,实在是蛋疼。我们转变下方案,为什么我要和原生每次token 传来传去,不能让一方统一管理吗?很明显这是可以的,所以的token 统一由原生管理,双方注册bridge 方法,不过这个方法是让原生给H5发送请求。其他一模一样,这下H5原生 就不用再去搞恶心的token 传递了,代码如下:
//发送请求
export function POSThybrid(url, data = {}) {
console.log(window.location.href);
console.log("后台url地址====" + url, "参数=====", data);
return new Promise((res, rej) => {
requestHybrid(url, data, (response) => {
if (response) {
switch (response.code) {
case 0:
res(response);
break;
//未登录
case 2:
goTo(goLogin);
break;
//餐厅金额不够去兑换
case 999:
res(response);
break;
default:
Toast.fail(response.message, 1);
res({ code: 10000 });
break;
}
}
})
})
}
//注册POST请求方法
function requestHybrid(url, data, callback) {
window.WebViewJavascriptBridge.callHandler(
'POST', { 'param': data, url: url }, (responseData, responseCallback) => {
formatData(responseData, callback)
}
)
}
前端如何调试
上面说到我们已经接近了原生和H5 token 交互问题,那么问题来了,H5怎么进行调试呢,我不能天天拉着原生陪我调试,玩耍吧,还能不能好好的写代码,不BB上代码:
新建2个js 一个用于和原生交互JS 一个本地H5
HTML
http-hybrid
function requestHybrid(url, data, callback) {
window.WebViewJavascriptBridge.callHandler(
'POST', { 'param': data, url: url }, (responseData, responseCallback) => {
formatData(responseData, callback)
}
)
}
//由于IOS安卓返回数据不同 格式化数据
function formatData(res, callback) {
let u = navigator.userAgent;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
if (isAndroid) {
try {
let data = JSON.parse(res);
console.log("前端打印的---->后台返回数据", data);
callback(data)
} catch (error) {
Toast.fail('网络连接错误!', 1);
}
}
if (isIOS) {
callback(res)
}
}
//发送请求
export function POSThybrid(url, data = {}) {
console.log(window.location.href);
console.log("后台url地址====" + url, "参数=====", data);
return new Promise((res, rej) => {
requestHybrid(url, data, (response) => {
if (response) {
switch (response.code) {
case 0:
res(response);
break;
//未登录
case 2:
goTo(goLogin);
break;
//餐厅金额不够去兑换
case 999:
res(response);
break;
default:
Toast.fail(response.message, 1);
res({ code: 10000 });
break;
}
}
})
})
}
http-web.js
const headers = {
'Accept': 'application/json',
'mode': "cors",
'QuanttDo-Token': window.token,
'Content-Type': 'application/json',
'token': ''
}
/**
*
* @param {Object} param0
*/
function request({ url, method = "post", data = {} }) {
return axios({
method,
url,
headers: { ...headers, 'QuanttDo-Token': window.token },
data: data
})
}
/**
*
* @param {String} url
* @param {Object} data
*/
function POSTweb(url, data) {
return request({ url, method: "post", data })
.then((res) => {
let { data } = res;
if (data) {
switch (data.code) {
case 0:
return data
//未登录
case 2:
goTo(goLogin);
break;
//餐厅金额不够去兑换
case 999:
return data;
default:
Toast.fail(data.message, 2);
return ({ code: 10000 });
}
}
return { code: 10000 };
})
.catch(function (error) {
Toast.fail('网络连接错误!', 1);
//一般为网关错误
throw error;
});
}
export { POSTweb };
然后根据启动方式不同走不同的入口即可
html
import { POSThybrid } from './http-hybrid';
import { POSTweb } from './http-web';
let POST = Function;
if (!!process.env.REACT_APP_hybrid) {
POST = POSThybrid
} else {
POST = POSTweb
}
export { POST };
配置 pack.json 文件
"start": "node scripts/start.js",
"start-h": "set REACT_APP_hybrid=true && node scripts/start.js",
这样你就和原生可以独立开发美滋滋,互不影响,美滋滋!