微信小程序 路由跳转 异步请求 存储数据,微信登录接口
1小程序路由跳转
这里的tabBar是底下的导航栏指定的页面
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 tabBar list中最多支持5个路径
参数
Object object
示例代码
{ "tabBar": { "list": [ { "pagePath": "index", "text": "首页" }, { "pagePath": "other", "text": "其他" } ] } }
wx.switchTab({ url: '/index' })
基础库 1.1.0 开始支持,低版本需做兼容处理 https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html
关闭所有页面,打开到应用内的某个页面
示例代码
wx.reLaunch({ url: 'test?id=1' })
// test Page({ onLoad (option) { console.log(option.query) } })
关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
示例代码
wx.redirectTo({ url: 'test?id=1' })
示例代码
wx.navigateTo({ url: 'test?id=1' })
// test.js Page({ onLoad(option) { console.log(option.query) } })
1.利用wx.navigateTo跳转到下一个页面的时候(这时候会执行onHide方法),下一个页面头部会有返回按钮
2.如果不想有返回按钮,可以用wx.redirectTo进行页面跳转(这时候关闭此页面,会执行onUnload生命周期,这样下一个页面就不会有返回按钮了,因为上一个页面已经被关闭了,没有页面可以返回)
关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。
示例代码
// 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码 // 此处是A页面 wx.navigateTo({ url: 'B?id=1' }) // 此处是B页面 wx.navigateTo({ url: 'C?id=1' }) // 在C页面内 navigateBack,将返回A页面 wx.navigateBack({ delta: 2 })
https://developers.weixin.qq.com/miniprogram/dev/api/wx.request.html
object.dataType 的合法值
示例代码
wx.request({ url: 'test.php', // 仅为示例,并非真实的接口地址 data: { x: '', y: '' }, header: { 'content-type': 'application/json' // 默认值 }, success(res) { console.log(res.data) } })
存到本地就是存到你的手机,侬懂了伐?
参数
string key: 本地缓存中指定的 key
any data: 需要存储的内容。只支持原生类型、Date、及能够通过JSON.stringify
序列化的对象。
示例代码
wx.setStorage({ key: 'key', data: 'value' }) try { wx.setStorageSync('key', 'value') } catch (e) { }
将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。数据存储生命周期跟小程序本身一致,即除用户主动删除或超过一定时间被自动清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
示例代码
wx.setStorage({ key: 'key', data: 'value' }) try { wx.setStorageSync('key', 'value') } catch (e) { }
上面的两个就是一个是同步的一个是异步的,还是有区别的,想用哪一个看你的业务来定
参数
string key: 本地缓存中指定的 key
返回值:any data,key对应的内容
示例代码
wx.getStorage({ key: 'key', success(res) { console.log(res.data) } }) try { const value = wx.getStorageSync('key') if (value) { // Do something with return value } } catch (e) { // Do something when catch error }
注意登录之后,发送cookie的时候一定要用同步的不要用异步的获取cookie
从本地缓存中异步获取指定 key 的内容
object.success 回调函数
Object res
示例代码
wx.getStorage({ key: 'key', success(res) { console.log(res.data) } }) try { const value = wx.getStorageSync('key') if (value) { // Do something with return value } } catch (e) { // Do something when catch error }
1.小程序登
[登入官方说明](https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html)
小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。
登录流程时序
说明:
-
调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
-
调用 code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。
之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
注意:
-
会话密钥
session_key
是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。 -
临时登录凭证 code 只能使用一次
小程序端执行wx.login后在回调函数中就能拿到上图的code,然后把这个code传给我们后端程序,后端拿到这个这个code后,可以请求code2Session接口拿到用的openid和session_key,openid是用户在微信中唯一标识,我们就可以把这个两个值(val)存起来,然后返回一个键(key)给小程序端,下次小程序请求我们后端的时候,带上这个key,我们就能找到这个val,就可以,这样就把登入做好了。
清除缓存代码实现
// wx.setStorage({ // // 异步存储 // key: 'key1', // data: 'value', // }) // wx.removeStorage({ // key: 'key1', // success: function(res) { // console.log(res) // // 回调函数的内容是清楚缓存成功 // }, // })
1.1wx.login(Object object)
调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户的唯一标识(openid)及本次登录的会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成。更多使用方法详见 小程序登录。
示例代码
wx.login({ success(res) { if (res.code) { // 发起网络请求 wx.request({ url: 'https://test.com/onLogin', data: { code: res.code }, success: function (res) { wx.setStorageSync('login_key', res.data.data.login_key); } }) } else { console.log('登录失败!' + res.errMsg) } } })
本接口应在服务器端调用,详细说明参见服务端API。
登录凭证校验。通过 wx.login() 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使用方法详见 小程序登录。
请求地址
GET https://api.weixin.qq.com/sns/jscode2sessionappid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
小程序代码
全局app.js
// 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId console.log(res.code) // 登录函数 页面来的是时候就已经登录了 wx.request({ url: this.globalData.DemoUrl + 'api/login/', method:"POST", data:{"code":res.code}, header:{"content-type":"application/json"}, success:function(res){ // console.log(res) wx.setStorage({ key: 'login_key', data: res.data.data, }) } }) } })
test2页面点击测试方法
click:function(){ console.log('1111') // wx.switchTab({ // // url: '/pages/test1/test1', // // 不跳转test1是引用全局配置中的tabbar list中没有写 最多写俩 // url: '/pages/test/test', // }) // wx.reLaunch({ // url: '/pages/test1/test1?key=123&aaa=bbb', // }) // 关闭所有页面,打开到应用内的某个页面 传参数的话在被跳转页面的onload页面能获取 // wx.navigateTo({ // url: '/pages/test/test?key=ttt&key2=rrr' // }) wx.request({ url: app.globalData.DemoUrl + "api/test/", method:"POST", data: {"login_key": wx.getStorageSync("login_key")}, header:{"content-type":"application/json"}, success:function(res){ console.log(res) } }) } })
服务器代码
目录结构
路由
url(r'^api/login/', views.Login.as_view()), url(r'^api/test/', views.Test.as_view()),
视图
from django.shortcuts import render # Create your views here. from rest_framework.views import APIView from rest_framework.response import Response from weixin import wx_login from django.core.cache import cache import hashlib,time from app01 import models class Login(APIView): def post(self,request,*args,**kwargs): params = request.data # print(params) if params.get('code'): # data=wx_login.login(params.get('code')) # print(data,type(data)) # {"session_key":"mTEOxtPDupgasomyx9qVWA==","openid":"obl-B4ktiLhm9z0jn94yF3e-7P-Y"} <class 'str'> data=wx_login.login(params.get('code')) md5= hashlib.md5() md5.update(str(time.time()).encode('utf-8')) md5.update(data.get('openid').encode('utf-8')) key= md5.hexdigest() val = f"{data.get('openid')}&{data.get('session_key')}" #yo用括号扩一下会自动转译成变量 cache.set(key,val) user_info=models.wx_user.objects.filter(openid=data.get('openid')).first() if not user_info: models.wx_user.objects.create(openid=data.get('openid')) #把加密后的Opid返回客户端,从redis中取出val 然后切分对比数据库 return Response({ 'msg':"ok", 'data':key }) return Response({ 'code':300, 'data':'缺少参数' }) class Test(APIView): def post(self,request,*args,**kwargs): params = request.data print(params,'kjlsjdfljsdl') if params.get('login_key'): data = cache.get(params.get('login_key')) if data: openid,session_key=data.split("&") return Response({ 'msg':'你登录成功了' }) else: return Response({ "msg":'login_key失效' }) return Response({ 'msg':'缺少参数' })
weixin/settings.py
AppSecret="79e1f339dc787236fa0082fdbb2c4ee0" AppID="wx3e0f7834c9f78a75" Auto_url="https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code"
weixin/wx_login.py
import requests from weixin import settings def login(code): res=requests.get(settings.Auto_url.format(settings.AppID,settings.AppSecret,code)) # return res.text #之前结果是str return res.json()
项目settings
# redis配置 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 100} # "PASSWORD": "123", } } } DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'wx', 'USER':'root', 'PASSWORD':"", 'HOST':'127.0.0.1', 'PORT':3306, # 'OPTIONS': {'charset': 'utf8mb4'}, } } #rest_framework记得注册