uni-app 微信中setStorageSync和getStorageSync诡异的问题!

bjp0bcyl  于 2022-11-02  发布在  uni-app
关注(0)|答案(7)|浏览(876)

问题描述

我想把用户登录状态保存到LocalStorage, 所以一直用 uni.setStorageSync()uni.getStorageSync() , 但是昨天遇到了一个奇怪的问题 当用 uni.setStorageSync("Expired", true) 来设置用户已经过期后 , 启动时获取到的 uni.getStorageSync("Expired") 一直是true, 哪怕启动后我重新获取了状态并设置了 uni.setStorageSync("Expired", false) , 可是启动依旧获取到true.
整整花费了1天时间最终只能用其他一种方式来解决.

复现步骤

微信H5(微信网页)使用中向第三方发送请求, 如果请求中带有过期请求, 我就跳转到一个网页:

// 跳转到处理Storage网页
uni.reLaunch({
	url: '/pages/loading?id=-1'
});

网页中我直接尝试重新获取请求, 如果依旧失败则让Storage设置成过期. 这时候用户打开网页就提示过期了. 以下是loading.vue

<template>
	           ``  此处省略
</template>
<script>
	export default {
		data() {
			return {
				IsExpiredSource:false,
                                Message : "页面中的提示!"
			}
		},
		components: {},
		methods: {
			async getdatas() {
                                // 像第三方请求获取登录状态
				let hhgghse = await this.get('https://第三方网页/GetJson')
                                // 如果获取不到任何信息过期
				if (!hhgghse.Id) {
                                       this.Message = "获取不到信息"!
					uni.hideLoading()
					return
				}
				// 如果从第三方请求会话一样, 需要重新生成会话设置成过期(防止继续用老会话)
				else if (this.IsExpiredSource)
				{
					let ddfer = uni.getStorageSync('gcook')
					if (ddfer.SessionId== hhgghse.SessionId)
					{
						// 直接让设置为过期
						uni.removeStorageSync('Expired')
						uni.setStorageSync('Expired', true)
						this.Message = "会话过期, 需要重新生成"!
						uni.hideLoading()
						return
					}

				}

				uni.removeStorageSync('times')
				uni.removeStorageSync('Expired')

				// 去掉过期信息 (这里重新打开又不生效)
				let sdee = new Date().getTime()
				uni.setStorageSync('times', sdee)
				uni.setStorageSync('Expired', false)

                                // 获取到的信息保存起来并跳转
				uni.setStorage({
					key: 'gcook',
					data: hhgghse,
					success: () => {
						uni.showModal({
							content: "数据重新获并保存!"
							showCancel:false,
							confirmText:this."OK",
							success: function (res) {
								uni.reLaunch({
									url: '/pages/index/index',
									success(){
                                                                                         //微信中去掉这个注解是解决问题的关键
											//location.reload();
										}
								})
								uni.hideLoading()
							}
						});

					}
				})
			}
		},
		onLoad: () => {

		},
		mounted() {
			uni.showLoading({
				title: 'loader...'
			})
			// 如果请求中带-1需要把本地Session和服务器Session对比, 相同就代表过期, 用户需要重新生成认证后打开本网页
			if (this.$route.query.id == -1)
			{
				this.IsExpiredSource = true
			}
			var ddfer = uni.getStorageSync('gcook')
			this.getdatas()
		}
	}
</script>
<style lang='scss' scoped>

</style>

从上面的代码可以简单看到. 用户在网页做操作时会像第三方发送请求, 如果第三方突然给你发送你的会话过期了, 则用户需要跳转到固定的loading页面, 并重新获取一个网页数据(相当于令牌), 如果获取不到提示用户无法获取, 如果成功获取了先检查是否和本地一样, 如果一样就手动保存Storage过期信息, 免得用户重复发送其他请求给第三方网页(都过期了没那个必要), 直到用户获取新的会话前, 我们网页都无法进行其他操作. 这时候需要启动中加一些代码. App.vue中 :

<script>
	export default {
		methods: {
		},
		onLaunch() {
			let ddfer = uni.getStorageSync('gcook')
			let times = uni.getStorageSync('times')
			let Expired = uni.getStorageSync('Expired')
			 // 缓存了8小时清除缓存
			let cerertr =  new Date().getTime()

                        // 如果是强制获取, 则需要直接跳转到相关页面检查对比第三方和本地会话
			if (Expired == true)
			{
				uni.reLaunch({
					url: '/pages/loading?id=-1'
				});
			}
                        // 超出了8小时重新获取第三方那边的新会话即可
			else if((cerertr -times) >(1000*60*60*8) || !times)
			{
				uni.reLaunch({
					url: '/pages/loading'
				});

			}
		}
	}
</script>

<style>
	@import"static/css/style.css";
</style>

这个页面说明了, 用户打开网页时先不要跳转默认页, 先检查是否会话过期, 如果过期了跳转到loading..., 并获取第三方请求, 如果是Expired成立, 则获取第三方请求直到第三方和本地会话Id不一样位置.

现在重新说一下整个流程. 用户微信中打开网页(电脑上浏览器没问题), 用着用着, 突然获取了Expired过期这个结果, 跳转到了Loading?=id=-1页面, 检查第三方和本地会话发现会话一样, 则手动写入了 uni.setStorageSync("Expired", true) , 用户只能关闭网页.
当用户第二次打开网页后获取uni.getStorageSync('Expired')发现过期, 又跳转到了Loading?=id=-1页面.但是如果用户在这个页面操作`uni.setStorageSync("Expired", false)并关闭网页重新打开, 刚这个操作失效了????

最后我发现直到第一个代码中的这个代码去掉注解(让它生效)刷新一下页面, 这样关闭网页下次打开上次保存的数据才会生效.....这算什么事儿??? (如果上上面的代码中找不到下面这行, 请自行Ctrl+F)

// 微信中去掉这个注解是解决问题的关键
//location.reload();

预期结果

微信打开后如果成功获取到了不一样的数据, 用 uni.setStorageSync("Expired", false) 保存后关闭网页, 下次打开时获取到的uni.getStorageSync('Expired')应该也是false.

实际结果

直到刷新页面, 否则微信刚打开就设置的 uni.setStorageSync("Expired", false) , 根本不会生效.

系统信息:

  • 发行平台: 微信里的网页(非小程序)
  • 操作系统 iOS 13.4.1
  • HBuilderX版本 2.6.16.20200424
  • uni-app版本 在哪儿查?
  • 设备信息 iphone 7

补充信息

我不知道这到底算什么逻辑? 难道说这是正常的吗? 我是说 微信中刚打开网页(非首次打开), 难道不刷新的话所有setStorageSync操作不会生效? 我是在是不能理解.

以上代码只是为了说明基本情况有去掉多余的代码, 如有什么问题 请留言讨论.

bfnvny8b

bfnvny8b1#

我猜你肯定是忽略了你存布尔值实际存进去的是一个string,会被JSON.stringfy序列化

4smxwvx5

4smxwvx52#

你可以去除网络请求相关的描述,你想反馈的是不是setStorageSync存储一个Date对象然后用getStorageSync取出在部分浏览器中和预期不符?

ddhy6vgd

ddhy6vgd3#

@EvanMaFYH , 这个错误我测试了无数次, 和bool类型无关, 因为我用string也是一样的结果.
@zhetengbiji , 你好像没听明白问题, 问题不是说存取和获取的值不同(因为使用中存储关闭后下次打开能正常获取), 而是刚启动时存储后不刷新页面直接关闭重新打开, 刚保存的不会生效, 这才是问题.

qvsjd97n

qvsjd97n4#

排除其他逻辑,你直接写一个新的工程单独测试storage接口是否存在问题。
如果单独测试能复现,试试其他设备能否复现。

jtoj6r0c

jtoj6r0c5#

@zhetengbiji , 我还是直接像现在一样通过存储后强制刷新页面来解决吧. 我近期估计没有时间去专门做个项目测试这个. 即便新工程能复现问题, 解决方案还不是存储后还得强制刷新一遍页面.

fumotvh3

fumotvh36#

@zhetengbiji , 我还是直接像现在一样通过存储后强制刷新页面来解决吧. 我近期估计没有时间去专门做个项目测试这个. 即便新工程能复现问题, 解决方案还不是存储后还得强制刷新一遍页面.

还是确定一下问题比较好,你所谓的“诡异”问题和奇特的”解决方案“,目前都还没有其他人提到过,有可能你哪里搞错了。

wz8daaqr

wz8daaqr7#

@zhetengbiji , 我如果搞错了应该Chrome测试也应该有问题. 目前只是在iphone上的微信H5才这样. 等更多人React再说吧那就.

相关问题