小程序
小游戏
企业微信
微信支付
扫描小程序码分享
有个问题困扰好久,我们小程序页面都需要确保登陆后,再用token进行数据请求。
如果将登陆写在在app.js的onLaunch,不能确保在页面onload的数据请求之前。因为,数据请求本来就是一个异步操作。
有没有更好的全局设置方法?
8 个回答
加粗
标红
插入代码
插入链接
插入图片
上传视频
写在request请求里吧,发起请求前从storage里拿token,如果没有拿到就调用登录接获取token,获取到token再继续发请求。相当于封装了请求预处理的统一拦截层,至于异步改同步的写法可以搜一下 async await,很方便使用
你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。
这个问题其实在小程序生成的的默认模板中就有实例代码
楼主解决了嘛?我之前是封装了请求他,判断是否登陆,登陆了继续请求接口未登录跳转到登陆页面。登陆成功返回页面。
现在微信新规禁止强制登陆了。想请教一下你那面如何解决的?
登录不要写在app.js中,登录一定要写在单独封装的request里面。
import Taro from '@tarojs/taro'import dva from '../dva'import { getStorageSyncLoginResult } from './index'import action from './action'import config from '../config'const makeOptions = (url, options) => { const defaultoptions = { url: undefined, method: 'GET', qs: undefined, body: undefined, headers: undefined, type: 'json', contentType: 'application/json', crossOrigin: true, credentials: undefined, customToken: false, showFailMsg: true, async: false, } let thisoptions = {} if (!options) { thisoptions = { url } } else { thisoptions = options if (url) { thisoptions.url = url } } thisoptions = Object.assign({}, defaultoptions, thisoptions, { qs: { ...thisoptions.qs, appId: config.appId } }) return thisoptions}const addQs = (url, qs) => { let queryString = '' let newUrl = url if (qs && typeof qs === 'object') { /* eslint no-restricted-syntax: 0 */ for (const k of Object.keys(qs)) { queryString += `&${k}=${qs[k]}` } if (queryString.length > 0) { if (url.split('?').length < 2) { queryString = queryString.substring(1) } else if (url.split('?')[1].length === 0) { queryString = queryString.substring(1) } } if (url.indexOf('?') === -1) { newUrl = `${url}?${queryString}` } else { newUrl = `${url}${queryString}` } } return newUrl}let token// invalidTryTimes 失效重试次数const request = (url, options, invalidTryTimes = 0) => { const opts = makeOptions(url, options) const { method, body, headers, qs, type, contentType } = opts let requestUrl = opts.url if (qs) requestUrl = addQs(requestUrl, qs) let header = headers if ((!headers || !headers['content-type']) && contentType) { header = Object.assign({}, headers, { 'content-type': contentType }) } if (opts.customToken) { if (!token) { const res = getStorageSyncLoginResult() token = res && res.token } header = { ...header, 'X-Custom-Token': token, } } const baseParam = { url: requestUrl, method, data: body, header, dataType: type, credentials: 'include', } return new Promise((resolve, reject) => { Taro.request(baseParam) .then(res => { let { statusCode, data } = res if ( statusCode < 200 || statusCode >= 300 || (data.code !== 0 && (data.code < 200 || data.code >= 300)) ) { let errors = { error: -1, request: url, errorMessage: '系统异常,请查看response', res, } if (data && typeof data === 'object') { errors = Object.assign({}, errors, data) } if (data.code === 401 && invalidTryTimes < 3 && !opts.async) {invalidTryTimes++// 如果接口返回失败后重新登录 dva
invalidTryTimes++
// 如果接口返回失败后重新登录
dva
.getDispatch()(action('user/login')) .then(_ => {token = null// 登录成功后清除token,重新发起请求 resolve(request(url, options, invalidTryTimes)) }) .catch(e => { reject(e) })
token = null
// 登录成功后清除token,重新发起请求
} else { console.log('request error ===>', errors) reject(errors) } } else { resolve(data) } }) .catch(err => { console.log('request error ===>', err) reject({ error: -1, message: '系统异常,请查看response', err, request: requestUrl, }) }) })}export default request
另外如果页面一开始有n个请求同时需要发出,那么需要一个checklogin的接口检测登录状态或者第一个请求完成后再发出后面n-1个请求。
具体看代码,
.getDispatch()(action(
'user/login'
))
.then(_ => {
token =
null
resolve(request(url, options, invalidTryTimes))
})
.
catch
(e => {
reject(e)
这里是登录的逻辑,user/login里面就是登录,登录同样调用的这个request,登录完成后异步获取用户信息,然后resolve返回重新请求后的数据。
你的问题其实不是什么token的问题,而是异步的问题吧?那就参考我的这篇的思路,思路:把openid换成token。
https://developers.weixin.qq.com/community/develop/doc/0008089ec2c6200b81e76e6ac56804
= =为啥有这种操作。如果所有页面 都是需要强登录的 ,默认给用户展示一个落地页面。页面有授权按钮。点击后授权手机号。注册并返回用户的token等信息。
app.js
wxlogin(){
return
new
Promise(
function
(resolve, reject) {
//登录请求...
resolve(res);
reject(err);
}
调用
app.wxlogin().then(res=>{}).
(err=>{})
写一个分离出来的登录页面,确认拿到token后跳转
关注后,可在微信内接收相应的重要提醒。
请使用微信扫描二维码关注 “微信开放社区” 公众号
写在request请求里吧,发起请求前从storage里拿token,如果没有拿到就调用登录接获取token,获取到token再继续发请求。相当于封装了请求预处理的统一拦截层,至于异步改同步的写法可以搜一下 async await,很方便使用
这个问题其实在小程序生成的的默认模板中就有实例代码
楼主解决了嘛?我之前是封装了请求他,判断是否登陆,登陆了继续请求接口未登录跳转到登陆页面。登陆成功返回页面。
现在微信新规禁止强制登陆了。想请教一下你那面如何解决的?
登录不要写在app.js中,登录一定要写在单独封装的request里面。
另外如果页面一开始有n个请求同时需要发出,那么需要一个checklogin的接口检测登录状态或者第一个请求完成后再发出后面n-1个请求。
具体看代码,
dva
.getDispatch()(action(
'user/login'
))
.then(_ => {
token =
null
// 登录成功后清除token,重新发起请求
resolve(request(url, options, invalidTryTimes))
})
.
catch
(e => {
reject(e)
})
这里是登录的逻辑,user/login里面就是登录,登录同样调用的这个request,登录完成后异步获取用户信息,然后resolve返回重新请求后的数据。
你的问题其实不是什么token的问题,而是异步的问题吧?那就参考我的这篇的思路,思路:把openid换成token。
https://developers.weixin.qq.com/community/develop/doc/0008089ec2c6200b81e76e6ac56804
= =为啥有这种操作。如果所有页面 都是需要强登录的 ,默认给用户展示一个落地页面。页面有授权按钮。点击后授权手机号。注册并返回用户的token等信息。
app.js
wxlogin(){
return
new
Promise(
function
(resolve, reject) {
//登录请求...
resolve(res);
reject(err);
}
}
调用
app.wxlogin().then(res=>{}).
catch
(err=>{})
写一个分离出来的登录页面,确认拿到token后跳转