一 项目背景
小程序的功能主要是扫描设备上的二维码报工,然后核算工时。由于甲方在哈尔滨亚冬会期间把外网全部都断掉了,致使微信小程序的后端接口无法连接,为了保证系统的稳定运行,公司决定开发H5版本备用(因为甲方作为大国企经常会有网络安全月等停掉外网的情况,但是车间可以部署内网wifi),现在我将适配中的关键技术点总计如下。
二 条件编译
为了方便代码管理,H5和小程序的代码是在一起的,这就需要用到条件编译,条件编译的详细用法在官网上有说明。(条件编译处理多端差异 | uni-app官网)。主要是page.json文件,之前在小程序是采用用户电话进行登录的,而在H5端是不能获取用户电话的,所以要单独写界面,这个H5的登录界面在微信小程序端是没必要存在的,而且小程序端对上传代码的大小是有限制的,代码包大了还得分包,比较麻烦,所以page.json文件就要进行条件编译。如下图所示:
三 关于扫描二维码
在我的小程序中,需要多处用到扫描二维码,在uniapp中,扫描二维码用到的函数为uni.scanCode,但是在H5的环境中这个函数是不起作用的,所以我用了DCloud插件市场的插件,这个插件的下载地址是H5调用摄像头识别二维码(原生H5调用,不需要任何sdk,本地扫描识别,不需要后端) - DCloud 插件市场
这个插件在使用的时候有几个点需要特别注意,现说明如下:
1 只有在https开头的情况下,才能调用摄像头
在开发环境下,只需要在mainfest.json中把https启动就可以了,如下图所示:
而在生产环境中(我是部署在nginx下),需要使用niginx发布https站点,我是按照https://zhuanlan.zhihu.com/p/339046686这个链接上一步步进行配置的,需要用到openssl生成https证书。首先需要下载openssl,然后在openssl.exe所在界面执行cmd命令,如下图所示:
我不知道我是哪里配置有问题,他说的那几个生成语句需要在前面加个openssl才好使,然后按照文章所说的,把以上四个文件放到nginx.conf文件的同级目录下,并且修改nginx.conf文件,如下图所示:
server {
listen 8080 ssl http2;
#listen 443 ssl http2;
server_name localhost;
ssl_certificate wish.crt;
ssl_certificate_key wish.key.unsecure;
# 分配20MB的共享内存缓存,不同工作进程共享TLS会话信息
# ssl_session_cache shared:SSL:20m;
# 设置会话缓存过期时间1h
ssl_session_timeout 60m;
# TLS协议的合理配置
# 指定TLS协议的版本,不安全的SSL2和SSL3要废弃掉
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 启用ssl_prefer_server_ciphers,用来告诉Nginx在TLS握手时启用服务器算法优先,由服务器选择适配算法而不是客户端
ssl_prefer_server_ciphers on;
# 优先选择支持前向加密的算法,且按照性能的优先顺序排列
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# 会话恢复的合理使用
# 配置会话票证,减少了TLS握手的开销
ssl_session_tickets on;
#charset koi8-r;
#access_log logs/host.access.log main;
#location / {
# root html;
# index index.html index.htm;
#}
}
待配置完成之后,重新启动nginx,就可以完成https站点的发布。
2 这个插件并不像uni.scanCode那样是有回调结果,他是个单独界面
我在微信小程序端实现扫描二维码这个功能的时候,是用的uniapp自带的uni.scanCode这个函数,这个函数是有回调的,而我用到的这个插件他的应用场景是个单独的页面,为了与微信小程序端的逻辑统一,我用了uni.$once和uni.$emit全局注册方法的方式来实现,关于uni.$once和uni.$emit,官方网站的详细介绍在这个链接上(uni-app官网),用来实现类似android的onActivityResult()回调,代码示例如下所示:
首先是二维码调用界面:
<template>
<view class="content">
<!--<ourLoading isFullScreen :active=showloading text="加载中..." />-->
<image class="logo" src="/static/logo.png"></image>
<!--<view class="text-area">
<text class="title">11111</text>
</view>-->
<button type="primary" style="width: 350rpx;margin-top: 40rpx;" @click="saomiao">开始扫描</button>
</view>
</template>
<script>
export default {
data() {
return {
showloading:false,
baseurl:'',
WORKERID:''
}
},
onLoad() {
this.baseurl=getApp().globalData.baseurl;
this.WORKERID=uni.getStorageSync("WORKERID");
this.saomiao();
},
methods: {
saomiao(){
//#ifdef MP-WEIXIN
uni.scanCode({
success: (res) => {
var WATERWALLQRCODE = res.result;
//this.showloading = true;
this.chagpinfo(WATERWALLQRCODE);
},
})
//#endif
//#ifdef H5
uni.$once('xunchagp',(res)=>{
this.chagpinfo(res);
})
uni.navigateTo({
url:'../index/scanqrcode?url=xunchaindex'
})
//#endif
},
chagpinfo(WATERWALLQRCODE){
//各种业务代码。。。。
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
然后是二维码拍摄界面,如下所示:
<template>
<view>
<mumu-get-qrcode @success='qrcodeSucess' @error="qrcodeError"></mumu-get-qrcode>
</view>
</template>
<script>
import mumuGetQrcode from '@/uni_modules/mumu-getQrcode/components/mumu-getQrcode/mumu-getQrcode.vue'
export default {
components: {
mumuGetQrcode
},
data() {
return {
url:'',
role:''
}
},
onLoad(e) {
this.url=e.url;
if(this.url=='scanjihua'){
this.role=e.role;
}
},
methods: {
qrcodeSucess(res) {
if(this.url=='xunchaindex'){
uni.$emit('xunchagp',res);
uni.navigateBack();
}
},
qrcodeError(err) {
console.log(err)
uni.showModal({
title: '摄像头授权失败',
content: '摄像头授权失败,请检测当前浏览器是否有摄像头权限。',
success: () => {
uni.navigateBack({})
}
})
}
}
}
</script>
<style>
</style>
当调用完成返回上一页时,上一界面注册的xunchagp方法将被调用。
3 他不能像uni.scanCode那样能选取相册中的图片
这个插件目前不能从相册中选取照片扫描二维码,如果读者们在做微信小程序到H5适配的时候,一定要注意这点
四 通过反向代理解决跨越的问题
所有的前后端分离的项目都有这个问题,我用的方法是通过反向代理的方式来处理他,在开发环境下,需要改动mainfest.json,如下图所示:
点击源码视图,在devServer节点下,添加proxy就可以了,上图中的momapi指的是url前缀。
在生产环境加,需要修改nginx.conf文件,增加location节点,如下图所示:
server {
#如果不开https,就把ssl http2去了
listen 8084 ssl http2;
server_name localhost;
ssl_certificate wish.crt;
ssl_certificate_key wish.key.unsecure;
# 分配20MB的共享内存缓存,不同工作进程共享TLS会话信息
# ssl_session_cache shared:SSL:20m;
# 设置会话缓存过期时间1h
ssl_session_timeout 60m;
# TLS协议的合理配置
# 指定TLS协议的版本,不安全的SSL2和SSL3要废弃掉
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 启用ssl_prefer_server_ciphers,用来告诉Nginx在TLS握手时启用服务器算法优先,由服务器选择适配算法而不是客户端
ssl_prefer_server_ciphers on;
# 优先选择支持前向加密的算法,且按照性能的优先顺序排列
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# 会话恢复的合理使用
# 配置会话票证,减少了TLS握手的开销
ssl_session_tickets on;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root D:\h5;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location /momapi/ {
proxy_pass https://172.16.240.53:30000;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
以上就是我遇到的问题,如果遇到新的问题会继续更新