跨平台应用开发进阶(二) :uni-app 实战
一、前言
在前期博文《》中,讲解了利用框架跨端开发的基础知识,此篇博文主要讲解实战流程及涉及知识点。
二、项目实战
2.1 样式框架
扩展组件符合组件规范,可直接应用。
若组件不符合规范,则需要在代码里手动和注册组件,然后才能使用。
标准js 和 浏览器js的区别
的代码,端运行于浏览器中。非端(包含小程序和),平台运行在中,平台运行在自带的引擎中,都没有运行在浏览器或里。
非端,虽不支持等浏览器的,但也支持标准。
不要把浏览器的扩展对象等价于标准。
的非端,一样支持标准,支持等语法,支持字符串、数字、时间、布尔值、数组、自定义对象等变量类型及各种处理方法。仅仅是不支持等浏览器专用对象。
2.2 路由跳转
保留当前页面,跳转到应用内的某个页面,使用可以返回到原页面。
注意⚠️:
页面跳转路径有层级限制,不能无限制跳转新页面;
跳转到 页面只能使用 跳转;
路由的目标页面必须是在里注册的页面。如果想打开,在平台可以使用 或组件;H5平台使用;小程序平台使用组件(url需在小程序的联网白名单中)。在中有个组件已对多端进行封装,可参考。
平台暂不支持以方式获取,请换用来获取,具体方式请参考上述示例。
关闭当前页面,返回上一页面或多级页面。可通过 g 获取当前的页面栈,决定需要返回几层。
关闭当前页面,跳转到应用内的某个页面。
关闭所有页面,打开到应用内的某个页面。
注意⚠️:
如果调用了 不会关闭,仅触发生命周期 。
H5端调用之后之前页面栈会销毁,但是无法清空浏览器之前的历史记录,此时不能返回,如果存在历史记录的话点击浏览器的返回按钮或者调用仍然可以导航到浏览器的其他历史记录。
跳转到 页面,并关闭其他所有非 页面。
2.3 请求后台
import {
baseURL
} from './config.js'
import {
getToken,
goToLogin
} from '@/common/util.js'
const setToken = (res) => {
if (res.hasOwnProperty("access_token")) {
getApp().globalData.token = getToken(res.token_type, res.access_token)
console.log('token info is: ', getApp().globalData.token)
}
if (res.hasOwnProperty('msg')) {
if (res.msg === '用户凭证已过期') {
goToLogin()
}
}
};
const handleErr = (err) => {
uni.hideLoading()
uni.showModal({
title: '提示',
content: err.errMsg,
showCancel: false,
success: function(res) {
if (res.confirm) {
// console.log('用户点击确定');
} else if (res.cancel) {
// console.log('用户点击取消');
}
}
});
};
const request = (url, params, method, tips) => {
uni.showLoading({
title: tips || "加载中..."
})
const curUrl = (url.indexOf('http') !== -1 || url.indexOf('https') !== -1) ? url : baseURL + url
console.log('The request url info is: ', curUrl)
console.log('The request params info is: ', params)
return new Promise((resolve, reject) => {
uni.request({
url: curUrl,
method: method || "POST",
header: {
'Content-Type': 'application/json',
'Authorization': getApp().globalData.token || 'Basic YXBwOmFwcA=='
},
data: params || {},
success(res) {
setToken(res.data)
resolve(res.data)
console.log('The request success return info is: ', res.data)
},
fail(err) {
reject(err)
console.log('The request fail return info is: ', err)
},
complete() {
uni.hideLoading()
}
})
}).catch(err => {
handleErr(err)
})
};
export {
requestForm,
requestJSON
}
// 获取token
export function getToken(token_type, access_token) {
let token = token_type.charAt(0).toUpperCase() + token_type.slice(1) + ' ' + access_token;
return token;
}
// Model提示是否返回登录页
export function goToLogin() {
uni.showModal({
title: '温馨提示',
content: "您还没有登录,请登录",
success: function(res) {
if (res.confirm) {
// console.log('用户点击确定');
uni.navigateTo({
url: '/pages/ucenter/userinfo/userinfo'
})
} else if (res.cancel) {
// console.log('用户点击取消');
}
}
})
}
// 引入工具类
import request from '@/service/request.js'
export function get(data){ //
return request({
url: '/forshop/getprefer',
method: 'GET',
contentType:'application/x-www-form-urlencoded',
data: data
})
}
注意⚠️:如果没有传入 参数,则会默认返回封装后的 对象。
以上为形式的接口请求方式。形式的接口请求方式为:
import { get } from "@/api/list/list"
// Await
async function request () {
var [err, res] = await get({
url: 'https://www.example.com/request'
});
console.log(res.data);
}
2.4 uni-app https请求方式
传统的 有以下安全性问题:
为解决安全通信问题, 应运而生。其实, 并不是新协议,而是站在的肩膀上,让 先和 ()通信,再由 和 通信,也就是说 使用了隧道进行通信。 通过使用 , 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。

2.4.1 加密
(1)对称密钥加密(),加密和解密使用同一密钥。

(2)非对称密钥加密,又称公开密钥加密(),加密和解密使用不同的密钥。
公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。 非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获取,因此通信发送方使用其私有密钥 进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确。

采用混合加密机制,使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率。

2.4.2 认证
通过使用证书来对通信方进行认证。
数字证书认证机构()是客户端与服务器双方都可信赖的第三方机构。 服务器的运营人员向 提出公开密钥的申请, 在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公开密钥证书后绑定在一起。 进行 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证, 如果验证通过,就可以开始通信了。
2.4.3 完整性保护
提供报文摘要功能来进行完整性保护。 也提供了 报文摘要功能,但不是安全的。例如报文内容被篡改之后,同时重新计算 的值,通信接收方是无法意识到发生了篡改。
的报文摘要功能之所以安全,是因为它结合了加密和认证这两个操作。试想一下,加密之后的报文,遭到篡改之后,也很难重新计算报文摘要,因为无法轻易获取明文。
2.4.4 HTTPS 的缺点
因为需要进行加密解密等过程,因此速度会更慢;
需要支付证书授权的高额费用。
应用请求方式,需要配合证书:
如果是访问的证书,应该是服务端配置,前端发起请求时,地址写成前缀即可,例如:
2.5 应用规划、配置和调整
并不是说有了证书就没事了,还要考虑应用中的使用问题,需要规划、服务器配置、应用调整等多个环节。
由于比 要消耗更多资源(主要是在建立握手连接阶段,之后还要对内容加密),所以对一般网站,只需要对部分地方采用,大部分开放内容是没必要的,具体取决于你的业务要求。比如对于很多安全要求较低的网站,完全不用也是可接受的。
某些页面是同时支持 和 ,还是只支持 、强制 ?
同时支持就是用户用什么协议访问都可以,那么用户的请求主要就是由页面本身的链接引导来的,因为一般用户不会自己特意去修改地址栏的。
一般我们的网站可以做成同时支持和,都可以访问。但是这就容易有后面说的混合内容或混合脚本的问题。
还可以规划为部分页面支持 ,一般公开页面不用,只是将部分地方的链接改为 就可以了。专门期望以 访问的页面中,引用的绝对可以明确的使用 链接。
是否强制 ?对于安全性高的网站或网站中的部分页面,可以强制使用访问, 即使用户在地址栏里手工把 改为 , 也会被自动重定向回 上。比如可以通过配置服务器 规则将这些 自动重定向到对应的 上(这样维护比较简单),而不用改应用。
2.6 应用市场上架
应用云打包时,提示如下校验信息:

其中,主要提示就是“当前应用缺少相关配置”,可通过如下措施解决:
打开项目的文件,切换到“源码视图”项
项目
在 "" -> "" 节点下添加 节点。
项目
在 "" -> "" 节点下添加 节点。
字符串类型,必填,隐私政策提示框配置策略,可取值,默认值为。
使用原生提示框模板,可自定义标题、内容已经按钮上的文本。
自定义隐私政策提示框,项目中推荐使用页面进行自定义,使用页面进行自定义。
不弹出隐私政策提示框
json格式,可选,模板提示框上显示的内容
"privacy": {
"prompt": "template",
"template": {
"title": "服务协议和隐私政策",
"message": " 请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。
你可阅读《服务协议》和《隐私政策》了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept": "我知道了",
"buttonRefuse": "暂不同意"
}
}