flask与小程序登录数据通信案例 第一步 小程序登录

app.js 首先在app.js里设置全局变量globalData

并在其中配置域名信息【和pycharm上的flask  ip接口一致】

//app.js
App({
    onLaunch: function () {
    },
    // globalData是一个全局数据对象,包含了以下几个属性1. userInfo: 用户信息,初始值为null,可以用来存储用户的登录信息或其他个人信息。
    // 2. version: 版本号,当前为1.0,用于标识系统或应用程序的版本。
    // 3. shopName: 商店名称,当前为"山东绿清源饮品有限公司",用于标识商店的名称。
    // 4. domain: 域名,当前为"http://192.168.124.46:8000/api",用于指定接口请求的域名。
    globalData: {
        userInfo: null,
        version: "1.0",
        shopName: "山东绿清源饮品有限公司",
        domain:"http://192.168.124.46:8000/api"
    },
    tip:function( params ){
        var that = this;
        var title = params.hasOwnProperty('title')?params['title']:'提示信息';
        var content = params.hasOwnProperty('content')?params['content']:'';
        wx.showModal({
            title: title,
            content: content,
            success: function(res) {

                if ( res.confirm ) {//点击确定
                    if( params.hasOwnProperty('cb_confirm') && typeof( params.cb_confirm ) == "function" ){
                        params.cb_confirm();
                    }
                }else{//点击否
                    if( params.hasOwnProperty('cb_cancel') && typeof( params.cb_cancel ) == "function" ){
                        params.cb_cancel();
                    }
                }
            }
        })
    },
    alert:function( params ){
        var title = params.hasOwnProperty('title')?params['title']:'提示信息';
        var content = params.hasOwnProperty('content')?params['content']:'';
        wx.showModal({
            title: title,
            content: content,
            showCancel:false,
            success: function(res) {
                if (res.confirm) {//用户点击确定
                    if( params.hasOwnProperty('cb_confirm') && typeof( params.cb_confirm ) == "function" ){
                        params.cb_confirm();
                    }
                }else{
                    if( params.hasOwnProperty('cb_cancel') && typeof( params.cb_cancel ) == "function" ){
                        params.cb_cancel();
                    }
                }
            }
        })
    },
    console:function( msg ){
        console.log( msg);
    },
    getRequestHeader:function(){
        return {
            'content-type': 'application/x-www-form-urlencoded',
            'Authorization': this.getCache("token")
        }
    },
    buildUrl:function (path,params) {
        var url = this.globalData.domain + path;
        var _paramUrl = "";
        if(params){
            _paramUrl = Object.keys(params).map(function(k){
                return [encodeURIComponent(k), encodeURIComponent(params[k])].join("=");
            }).join("&");
            _paramUrl ="?" + _paramUrl;
        }
        return url + _paramUrl;

    },

    getCache:function (key){
        var value = undefined;
        try {
            value = wx.getStorageSync(key);
        } catch (e) {

        }
        return value;
    },
    setCache:function (key,value) {
        wx.setStorage({
            key:key,
            data:value
        });

    }



});

然后按照微信官方捣鼓的微信官方的微信账号的登陆系统登录进程进行一步一步的搭配。

微信小程序 用户信息·小程序登录_w3cschool

mina/pages/index/index.js

//login.js
//获取应用实例
var app = getApp();
Page({
    data: {
        remind: '加载中',
        angle: 0,
        userInfo: {},
        regFlag:true
    },
    goToIndex: function () {
        wx.switchTab({
            url: '/pages/food/index',
        });
    },
    onLoad: function () {
        wx.setNavigationBarTitle({
            title: app.globalData.shopName
        });
        this.checkLogin();
    },
    onShow: function () {

    },
    onReady: function () {
        var that = this;
        setTimeout(function () {
            that.setData({
                remind: ''
            });
        }, 1000);
        wx.onAccelerometerChange(function (res) {
            var angle = -(res.x * 30).toFixed(1);
            if (angle > 14) {
                angle = 14;
            }
            else if (angle < -14) {
                angle = -14;
            }
            if (that.data.angle !== angle) {
                that.setData({
                    angle: angle
                });
            }
        });
    },
    checkLogin:function(){
        var that = this;
         // 使用小程序登录流程时序:
         //wx.login()是微信小程序提供的一个登录接口,用于获取用户登录凭证(code)。该接口需要传入一个success回调函数,在登录成功时会返回一个包含登录凭证的res对象。
         // 1 首先调用wx.login()方法,当登录成功时,会执行success回调函数。在回调函数中,通过判断res.code是否存在来判断登录是否成功。
        // 如果res.code不存在,说明登录失败,会弹出一个提示框显示"登录失败,请再次点击~~"。
         wx.login({
             success:function( res ){
                 if( !res.code ){
                    app.alert( { 'content':'登录失败,请再次点击~~' } );
                    return;
                 }

                 // 2  使用微信小程序的wx.request()方法发送一个POST请求

                 wx.request({
                    //  url: 请求的地址是通过app.buildUrl(‘/member/check-reg’)方法构建的。
                    url:app.buildUrl( '/member/check-reg' ),
                    //  header: 请求头部信息是通过app.getRequestHeader()方法获取的。
                    header:app.getRequestHeader(),
                    //  method: 请求方法是POST。
                    method:'POST',
                    //  data: 请求的数据是一个对象,包含一个code属性,值为res.code。
                    data:{ code:res.code },
                    //  success: 请求成功后的回调函数。
                    success:function( res ){
                        if( res.data.code != 200 ){
                            that.setData({
                                regFlag:false
                            });
                            return;
                        }
                        // 如果res.data.code等于200,它会调用app.setCache("token", res.data.data.token)来设置一个名为"token"的缓存,并将res.data.data.token作为值
                        app.setCache( "token",res.data.data.token );
                        //that.goToIndex();
                    }
                });
             }
         });
    },
    login:function( e ){
        var that = this;
        if( !e.detail.userInfo ){
            app.alert( { 'content':'登录失败,请再次点击~~' } );
            return;
        }

        var data = e.detail.userInfo;
        wx.login({
            success:function( res ){
                if( !res.code ){
                    app.alert( { 'content':'登录失败,请再次点击~~' } );
                    return;
                }
                data['code'] = res.code;
                wx.request({
                    url:app.buildUrl( '/member/login' ),
                    header:app.getRequestHeader(),
                    method:'POST',
                    data:data,
                    success:function( res ){
                        if( res.data.code != 200 ){
                            app.alert( { 'content':res.data.msg } );
                            return;
                        }
                        app.setCache( "token",res.data.data.token );
                        that.goToIndex();
                    }
                });
            }
        });
    }
});



RequestTask | 微信开放文档  发起 HTTPS 网络请求。

request   美  /rɪˈkwest/    v.<正式>请求,要求

小程序和flask项目是怎么实现数据交互的?

小程序Flask项目都可以通过数据交互来实现 端的通信 

下面我将分别介绍它们的实现方式:

对于小程序,数据交互通常使用微信提供的小程序API进行实现。具体步骤如下:1 wxml前端 通过后端js发送wx.request()方法发送HTTP请求到flask后端服务器
2 js后端处理请求:后端服务器使用Flask框架接收到请求后,可以通过Flask提供的路由功能进行处理。


www.py
from app import app
'''
蓝图功能,对所有的url进行蓝图功能配置
'''
from web.controllers.api import route_api
app.register_blueprint( route_api,url_prefix = "/api" )
web/controllers/api/__init__.py
# -*- coding: utf-8 -*-
from flask import Blueprint
route_api = Blueprint( 'api_page',__name__ )
from web.controllers.api.Member import *
from web.controllers.api.Food import *
from web.controllers.api.Order import *

from web.controllers.api.Cart import *


@route_api.route("/")
def index():
    return "Mina Api V1.0~~"
问题:此处的__init__.py文件的作用是什么?为什么非要捣鼓这个__init__.py文件?这个__init__.py文件是不是一无是处?可不可以置之不理?
web/controllers/api/Member.py
# -*- coding: utf-8 -*-
from web.controllers.api import route_api
from  flask import request,jsonify,g
from app import  app,db
import requests,json
from common.models.member.Member import Member
from common.models.member.OauthMemberBind import OauthMemberBind
from common.models.food.WxShareHistory import WxShareHistory
from common.libs.Helper import getCurrentDate
from common.libs.member.MemberService import MemberService

@route_api.route("/member/login",methods = [ "GET","POST" ])
def login():
    resp = { 'code':200 ,'msg':'操作成功~','data':{} }
    req = request.values
    code = req['code'] if 'code' in req else ''
    if not code or len( code ) < 1:
        resp['code'] = -1
        resp['msg'] = "需要code"
        return jsonify(resp)


    openid = MemberService.getWeChatOpenId( code )
    if openid is None:
        resp['code'] = -1
        resp['msg'] = "调用微信出错"
        return jsonify(resp)

    nickname = req['nickName'] if 'nickName' in req else ''
    sex = req['gender'] if 'gender' in req else 0
    avatar = req['avatarUrl'] if 'avatarUrl' in req else ''
    '''
        判断是否已经测试过,注册了直接返回一些信息
    '''
    bind_info = OauthMemberBind.query.filter_by( openid = openid,type = 1 ).first()
    if not bind_info:
        model_member = Member()
        model_member.nickname = nickname
        model_member.sex = sex
        model_member.avatar = avatar
        model_member.salt = MemberService.geneSalt()
        model_member.updated_time = model_member.created_time = getCurrentDate()
        db.session.add(model_member)
        db.session.commit()

        model_bind = OauthMemberBind()
        model_bind.member_id = model_member.id
        model_bind.type = 1
        model_bind.openid = openid
        model_bind.extra = ''
        model_bind.updated_time = model_bind.created_time = getCurrentDate()
        db.session.add(model_bind)
        db.session.commit()

        bind_info = model_bind

    member_info = Member.query.filter_by(id = bind_info.member_id).first()
    token = "%s#%s" % (MemberService.geneAuthCode(member_info), member_info.id)
    resp['data'] = {'token': token}
    return jsonify( resp )


@route_api.route("/member/check-reg",methods = [ "GET","POST" ])
def checkReg():
    resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
    req = request.values
    code = req['code'] if 'code' in req else ''
    if not code or len(code) < 1:
        resp['code'] = -1
        resp['msg'] = "需要code"
        return jsonify(resp)

    openid = MemberService.getWeChatOpenId(code)
    if openid is None:
        resp['code'] = -1
        resp['msg'] = "调用微信出错"
        return jsonify(resp)

    bind_info = OauthMemberBind.query.filter_by(openid=openid, type=1).first()
    if not bind_info:
        resp['code'] = -1
        resp['msg'] = "未绑定"
        return jsonify(resp)

    member_info = Member.query.filter_by( id = bind_info.member_id).first()
    if not member_info:
        resp['code'] = -1
        resp['msg'] = "未查询到绑定信息"
        return jsonify(resp)

    token = "%s#%s"%( MemberService.geneAuthCode( member_info ),member_info.id )
    resp['data'] = { 'token':token }
    return jsonify(resp)

@route_api.route("/member/share",methods = [ "POST" ])
def memberShare():
    resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
    req = request.values
    url = req['url'] if 'url' in req else ''
    member_info = g.member_info
    model_share = WxShareHistory()     #初始化数据模型
    if member_info:
        model_share.member_id = member_info.id
    model_share.share_url = url
    model_share.created_time = getCurrentDate()
    db.session.add(model_share)
    db.session.commit()
    return jsonify(resp)


@route_api.route("/member/info")
def memberInfo():
    resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
    member_info = g.member_info
    resp['data']['info'] = {
        "nickname":member_info.nickname,
        "avatar_url":member_info.avatar
    }
    return jsonify(resp)
commonlibs/member/MemberServices.py
# -*- coding: utf-8 -*-
import hashlib,requests,random,string,json
from app import  app
class MemberService():

    @staticmethod
    def geneAuthCode( member_info = None ):
        m = hashlib.md5()
        str = "%s-%s-%s" % ( member_info.id, member_info.salt,member_info.status)
        m.update(str.encode("utf-8"))
        return m.hexdigest()

    @staticmethod
    def geneSalt( length = 16 ):
        keylist = [ random.choice( ( string.ascii_letters + string.digits ) ) for i in range( length ) ]
        return ( "".join( keylist ) )

    @staticmethod
    def getWeChatOpenId( code ):
        url = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code" \
            .format(app.config['MINA_APP']['appid'], app.config['MINA_APP']['appkey'], code)
        r = requests.get(url)
        res = json.loads(r.text)
        openid = None
        if 'openid' in res:
            openid = res['openid']
        return openid
getweChatOpenId (code)

@staticmethod是Python中的一个装饰器,用于定义静态方法。静态方法是属于类的方法,不需要实例化对象就可以调用。在静态方法中,无法访问类的属性和实例属性,只能访问类的静态属性。

在上面的代码中,@staticmethod装饰器用于定义getWeChatOpenId方法为静态方法。这个方法用于获取微信的OpenID,通过传入一个code参数,发送请求到微信API获取OpenID,并返回OpenID。

数据预拉取 | 微信开放文档 按官网文档明述,code也是需要自己去拉取的。

小程序登录 | 微信开放文档

code2Session

登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使用方法详见小程序登录。

  1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
  2. 临时登录凭证 code 只能使用一次
code 返回数据示例

{
"openid":"xxxxxx",
"session_key":"xxxxx",
"unionid":"xxxxx",
"errcode":0,
"errmsg":"xxxxx"
}

调用方式

HTTPS 调用

3 数据处理与返回后端服务器根据请求的内容进行相应的数据处理,

可以从SQL数据库中获取数据,或者进行其他业务逻辑处理。处理完成后,将结果封装成JSON格式 返回给小程序前端
前端接收数据小程序前端wxml 通过回调函数success 接收到后端js 返回的数据,并进行相应的展示或处理。

问题:小程序的回调函数是什么?

RequestTask | 微信开放文档
赘述嘟喃绕口令:对于Flask项目,数据交互通常使用HTTP协议进行实现。

具体步骤如下:

1 前端发送请求:前端通过浏览器或其他客户端发送HTTP请求到Flask后端服务器。
2 后端处理请求:Flask后端服务器使用路由功能接收到请求后,根据请求的URL和HTTP方法进行相应的处理。
3 数据处理与返回:后端服务器根据请求的内容进行相应的数据处理,可以从数据库中获取数据,或者进行其他业务逻辑处理。处理完成后,将结果封装成JSON格式返回给前端。
前端接收数据:前端通过回调函数接收到后端返回的数据,并进行相应的展示或处理。

到这,Flask和微信小程序的数据交互用以微信登录就完成啦!  之后就是更多功能不同数据的来回通信啦!

Thanks for the time

Best Wishs

app.setCache()

app.setCache()是一个函数,用于设置应用程序的缓存策略。缓存是指将数据存储在内存或磁盘中,以便在后续的请求中可以更快地获取数据,提高应用程序的性能和响应速度。

具体来说,app.setCache()函数可以用来设置以下几个方面的缓存策略:

  1. 缓存模式:可以设置为"no-cache"、“default”、“force-cache”、"only-if-cached"等不同的模式。其中,"no-cache"表示不使用缓存,每次请求都会重新获取数据;"default"表示使用默认的缓存策略;"force-cache"表示强制使用缓存,即使缓存已过期;"only-if-cached"表示只使用缓存,如果缓存不存在则返回错误。

  2. 缓存过期时间:可以设置缓存的过期时间,即数据在缓存中的有效期限。过期时间可以根据具体需求进行设置,例如设置为一小时、一天等。

  3. 缓存大小:可以设置缓存的最大大小,即可以存储的数据量。当缓存达到最大大小时,新的数据将替换掉最旧的数据。

通过设置合适的缓存策略,可以有效地提高应用程序的性能和用户体验。

缓存是一种用于临时存储数据的技术,它可以提高数据访问的速度和效率。在计算机系统中,缓存通常位于CPU和主存之间,用于存储最近或频繁访问的数据,以便快速响应后续的读取请求。

缓存的工作原理是通过将数据复制到更快的存储介质中,以便在需要时能够更快地获取数据。当需要访问某个数据时,系统首先检查缓存中是否存在该数据。如果存在,则可以直接从缓存中获取,避免了从较慢的主存或磁盘中读取数据的时间消耗。如果缓存中不存在需要的数据,则系统会从主存或磁盘中读取,并将其存储到缓存中,以备后续使用。

缓存可以提高系统的响应速度和性能,特别是对于频繁访问的数据。常见的应用场景包括网页浏览器中的网页缓存、数据库系统中的查询结果缓存等。

app.setCache是一个函数,用于在应用程序中设置缓存。通过使用缓存,应用程序可以在后续的请求中快速访问已经获取或计算过的数据,而不需要再次从服务器或其他地方获取。这可以提高应用程序的性能和响应速度。

具体来说,app.setCache函数可以接受两个参数:键和值。键是用于标识缓存数据的唯一标识符,而值则是要缓存的数据本身。当应用程序需要访问某个数据时,它可以首先检查缓存中是否存在该数据,如果存在,则可以直接从缓存中获取,而不需要进行耗时的网络请求或计算。

使用app.setCache函数可以根据具体的应用场景来设置缓存策略,例如在获取网络数据后将其缓存起来,或者在计算结果后将结果缓存起来。同时,还可以设置缓存的有效期,以确保缓存数据的及时更新

app.js

     getCache:function (key){
        var value = undefined;
        try {
            value = wx.getStorageSync(key);
        } catch (e) {

        }
        return value;
    },
    // setCache是一个函数,用于将数据存储到微信小程序的本地缓存中。
    它接受两个参数:key和value。key是要存储的数据的键名,value是要存储的数据的值。
    setCache:function (key,value) {
        // 通过调用wx.setStorage方法来实现的,该方法会将数据以键值对的形式存储到本地缓存中。
        wx.setStorage({
            key:key,
            data:value
        });

    }

});

wx.setStorage(Object object) | 微信开放文档 

将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xinzheng新政

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值