第一种方法(需要与后端联调鉴权)❌非必要不推荐
微信的使用
官方文档:developers.weixin.qq.com/doc/offiacc...
ps: 如果是微信小程序页面使用组件挂载h5页面,且该H5页面的域名地址与微信的请求白名单域名相同(意思就是该域名已配置在小程序的开发配置中),则不需要 绑定域名
安装微信jsSDK包
scss
// 微信
npm install weixin-js-sdk --save
// 钉钉
npm install dingtalk-jsapi --save
或者 如果是纯html页面也可以用<script>方式引入
向后端发起请求获取鉴权参数
因为上面说过了,如果小程序的后端请求地址有请求配置参数的接口即可在H5发起请求,因为此文件引入的 axios,未设置请求地址则会去使用顶级对象小程序的axios请求地址去发起请求(前提条件:服务端开发者已提供该请求接口)
- 先在此文件单独引入axios库(不能用已封装好的axios)
- 在页面引入 sdk
- 发起获取小程序配置的接口
- 通过JSSDK的config接口注入权限验证配置(config如果失败则会调error的函数,如果成功则调ready的函数) 钉钉新版不需要鉴权
- 鉴权完成后即可调用需要使用的 jsapi
钉钉的jsspi名称需注意新版和旧版的api名字,旧版是三段式,新版是一段式
js
// 使用vue2写法
<script>
import * as wx from "weixin-js-sdk";
import * as dd from "dingtalk-jsapi";
import axios from "axios";
export default {
data() {
return {};
},
created() {
let params = window.location.search || window.location.hash; //判断是从哪个小程序进入
if (params.indexOf("WeChat") > -1) {
this.userAgent = "WeChat";
this.initJSSDK();
} else if (params.indexOf("DingTalk") > -1) {
this.userAgent = "DingTalk";
this.initDDJSSDK();
}
},
methods: {
// 点击去扫码
toScan() {
this.userAgent === "WeChat" ? this.wxScan() : this.ddScan();
},
/**
* *钉钉扫码(好像无需dd.config鉴权)
*/
ddScan() {
dd.scan({
type: "qr",
success: (res) => {
const { code } = res;
alert("code:", code);
},
fail: (err) => {
alert("error", err);
},
complete: (comp) => {
alert("complete:", comp);
},
});
},
/**
* *钉钉jssdk初始化
*/
async initDDJSSDK() {
try {
// 调用微信官方提供的接口获取配置信息
const response = await axios.get("/get-dd-config");
const data = response.data;
dd.config({
agentId: data.agentId, // 必填,微应用ID
corpId: data.corpId, //必填,企业ID
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,自定义固定字符串。
signature: data.signature, // 必填,签名
type: 0, //选填。0表示微应用的jsapi,1表示服务窗的jsapi;不填默认为0。该参数从dingtalk.js的0.8.3版本开始支持
jsApiList: ["scan"], // 必填,需要使用的jsapi列表,注意:不要带dd,需注意新版和旧版的api名称不一致
});
dd.ready(function () {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是异步的
// 所以此处调用的函数应该放在ready函数中
alert("钉钉配置获取成功");
});
dd.error(function (res) {
// config信息验证失败会执行error函数,如缺少appId等情况
// 打印出错信息
console.error("钉钉配置失败:", res);
alert("dd error: " + JSON.stringify(err));
});
} catch (error) {
console.error("获取钉钉配置信息失败:", error);
alert(`获取钉钉配置信息失败+${error}`);
}
},
/**
* *微信扫码
*/
wxScan() {
wx.scanQRCode({
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
success: function (res) {
var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
alert(`微信扫码结果:${result}`);
},
});
},
/**
* * 微信jsSdk初始化
*/
async initJSSDK() {
try {
// 调用微信官方提供的接口获取配置信息
const response = await axios.get("/get-wx-config");
const data = response.data;
wx.config({
debug: false, // 开启调试模式
appId: data.appId, // 必填,公众号的唯一标识
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,生成签名的随机串
signature: data.signature, // 必填,签名
jsApiList: ["scanQRCode"], // 必填,需要使用的JS接口列表
});
wx.ready(function () {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是异步的
// 所以此处调用的函数应该放在ready函数中
alert("微信配置获取成功");
});
wx.error(function (res) {
// config信息验证失败会执行error函数,如缺少appId等情况
// 打印出错信息
console.error("微信配置失败:", res);
alert(`微信配置失败+${error}`);
});
} catch (error) {
console.error("获取微信配置信息失败:", error);
alert(`获取微信配置信息失败+${error}`);
}
},
},
};
</script>
第二种方法
1.微信端 使用 ****html5-qrcode 插件实现扫码功能
html5-qrcode是轻量级和跨平台的QR码和条形码扫码的JS库,集成二维码、条形码和其他一些类型的代码扫描功能,代码依赖于Zxing-js库优势:
- 支持扫描不同类型的条形码和二维码
- 支持不同平台,Android、IOS、MacOS、Windows或Linux
- 支持不同的浏览器,如Chrome、Firefox、Safari、Edge
- 支持相机扫描以及本地文件
- 支持自定义,如闪光/火炬支持、缩放等
注意:直接访问摄像头,涉及到隐私,所以环境必须是 HTTPS
微信端:小程序嵌入的web-view还是浏览器直接访问都是可以调起原生扫码功能,不需要使用wx-jssdk的api
安装插件
npm i html5-qrcode
💥💥💥 html5-qrcode 关键代码
js
<template>
<div class="qrcode">
<div class="icon" @click="stop">
<van-icon name="arrow-left" size="14px" />
</div>
<div id="reader"></div>
</div>
</template>
<script>
import { Html5Qrcode } from "html5-qrcode";
export default {
data() {
return {
html5QrCode: null,
};
},
created() {
this.$toast.loading({
message: "加载中...",
forbidClick: true,
duration: 0,
});
this.getCameras();
},
beforeDestroy() {
if (this.html5QrCode) this.stop();
},
methods: {
/**
* ! 获取相机权限
*/
getCameras() {
Html5Qrcode.getCameras()
.then((devices) => {
if (devices && devices.length) {
this.html5QrCode = new Html5Qrcode("reader");
this.start();
this.$toast.clear();
}
})
.catch((err) => {
// handle err
this.html5QrCode = new Html5Qrcode("reader");
this.error = "ERROR: 您需要授予相机访问权限";
// this.$emit("err", this.error);
alert(`ERROR: ${err}`);
this.$toast.clear();
});
},
/**
* ! 开始扫码
*/
start() {
this.html5QrCode
.start(
{ facingMode: "environment" }, // environment后置摄像头 user前置摄像头
{
fps: 2, // 可选,每秒帧扫描二维码
qrbox: { width: 250, height: 250 }, //扫码框大小
aspectRatio: 1.92, // 可选,视频馈送需要的纵横比,(4:3--1.333334, 16:9--1.777778, 1:1--1.0)传递错误的纵横比会导致视频不显示
},
(decodedText, decodedResult) => {
// this.$emit("ok", decodedText);
// alert(`decodedText:${decodedText}${JSON.stringify(decodedResult)}`);
// alert(`decodedText:${decodedText}`);
this.$toast({
type: "success",
message: "扫码成功",
duration: 1000,
});
if (this.html5QrCode) this.stop();
setTimeout(() => {
this.$router.push({
path: "/ticket",
query: { id: decodedText },
});
}, 500);
}
)
.catch((err) => {
alert("ERROR: ", err);
this.$toast.clear();
// 错误信息处理仅供参考,具体情况看输出!!!
if (typeof err == "string") {
// this.$toast(err)
} else {
if (err.name == "NotAllowedError")
return this.$toast("您需要授予相机访问权限");
if (err.name == "NotFoundError")
return this.$toast("这个设备上没有摄像头");
if (err.name == "NotSupportedError")
return this.$toast(
"摄像头访问只支持在安全的上下文中,如https或localhost"
);
if (err.name == "NotReadableError")
return this.$toast("相机被占用");
if (err.name == "OverconstrainedError")
return this.$toast("安装摄像头不合适");
if (err.name == "StreamApiNotSupportedError")
return this.$toast("此浏览器不支持流API");
}
});
},
/**
* ! 停止扫码
*/
stop() {
this.$router.go(-1);
this.html5QrCode
.stop()
.then((ignore) => {
// QR Code scanning is stopped.
console.log("QR Code scanning stopped.");
})
.catch((err) => {
// Stop failed, handle it.
console.log("Unable to stop scanning.");
});
},
},
};
</script>
<style lang="scss" scoped>
.qrcode {
position: relative;
height: 100vh;
width: 100vw;
background: rgba($color : #000000, $alpha : 0.48);
.icon {
position: absolute;
left: 20px;
top: 20px;
z-index: 99;
width: 20px;
height: 20px;
background-color: #fff;
color: black;
font-weight: bold;
font-size: 16px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
}
#reader {
// width: 100vw;
// height: 100vh;
// top: 50%;
// left: 0;
// transform: translateY(25%);
}
</style>
2.钉钉小程序的使用方法
钉钉的 web-view 容器环境与钉钉的浏览器 h5 容器环境不相同,在钉钉直接访问链接地址打开h5,会发现使用 html5-qrcode 插件可以扫码,但是在web-view中就无法拉起相机功能
官方人员回答的是目前 web-view 还不支持h5端的jsapi的方法,如果需要使用h5的扫码功能,可以使用 dd.openLink 方法进行跳转到钉钉浏览器进行访问,就可以打开扫码功能了,这个时候我们又会发现,如果你引入了dd-jssdk,还可以直接使用dd.scan 钉钉自带的扫码功能
钉钉web-view文档
小程序使用H5微应用客户端API
dd.openLink 在小程序端是不支持的,只能先引入h5微应用的jsapi,在去调用jsapi的openLink方法
官网引入的方法
小程序使用H5微应用客户端API
我的方法
小程序端 引入客户端sdk 不用 使用 openLink 即可,
js
npm install dingtalk-jsapi --save
// 在web-view的组件中单独引入,起一个别名不要用dd,会与小程序的全局dd冲突
import * as mydd from 'dingtalk-jsapi'; // 此方式为整体加载,也可按需进行加载
mydd.openLink({
url: '跳转的地址',
success: () => {},
fail: () => {},
complete: () => {},
});
h5页面端 先引入客户端sdk
使用 dd.scan 就好了(就可以拉起钉钉原生的扫码功能)
js
/**
* *钉钉扫码
*/
ddScan() {
dd.scan({
type: "qr",
success: (res) => {
const { text } = res;
this.$toast({
type: "success",
message: "扫码成功",
duration: 1000,
});
setTimeout(() => {
this.$router.push({
path: "/ticket",
query: { id: text },
});
}, 500);
},
fail: (err) => {
alert("error", err);
},
complete: (comp) => {
alert("complete:", comp);
},
});
},