白马过隙,转瞬之间 23 年的进度条已经快达到 100%,在迎接 24 年到来的同时,我们不妨来回顾一下这充满许多值得回忆时刻的 23年。过去的一年里,我们都经历了很多事情,或许经历了许多重要的时刻和学习机会;或许扩展了自己的知识领域;或许提升了自己的技术水平等等。接下来我来分享一下我在 23 年的一些代码笔记以及实战项目笔记。
这篇文章是本专栏 uni-app 的项目经验篇,该文章将为大家分享在 uni-app 开发中的项目实战经验,本篇文章的主题是关于小程序上传图片官方 API 的使用,以及一些版本问题等等。除此之外,还有前段时间新发布的小程序隐私保护指引设置的新内容,包括如何解决类似隐私问题和如何设置隐私保护指引。
本专栏主要是分享和介绍从零到一学习和使用的 uni-app 的笔记和个人经验。通过个人的学习经验和工作经验来给大家分享关于 uni-app 开发的技巧,以及快速入门的诀窍等等。
在小程序中上传图片是很常见的交互功能,也是软件开发中不可缺少的功能,无论是在浏览器还是小程序中,都有很多需要用户上传图片的操作,接下来我们一起来看下有哪些应用场景,然后具体分析下需求。
应用场景:注册审核,在注册的流程中可能涉及到上传图片的需求,比如说身份证审核,个人信息等等审核,这个时候就需要用户上传图片到后台,进行审核;修改头像,这个功能是最常见的一个上传图片应用场景,用户从相册上传一张图片作为用户头像;表单提交,这个也是经常可以见到的应用场景,比如说问卷调查中需要上传图片的模块,或者任务提交的上传图片和上传任务描述这种应用场景。
需求分析:这里以注册审核的应用场景为例子,我们来分析一下这个需求,比如说该小程序注册要走审核流程,需要上传图片进行审核,首先授权完手机号码,然后填写用户的个人资料,如地址信息等等,接下来是上传图片的模块,比如说审核身份证、银行卡、健康证、认证资料等等,这些步骤都涉及到上传图片的功能。
分析完应用场景和需求之后,我们一起来看看在 uni-app 中可以用哪些 API 来实现上传图片的功能。
uni.chooseImage() 是 uniapp 框架提供的一个 API,用于从本地相册或相机选择图片。 使用该方法可以打开系统的图片选择界面,让用户选择一张或多张图片。选择完成后,可以获取到选择的图片的临时文件路径。
?PS:App端如需要更丰富的相机拍照API(如直接调用前置摄像头),参考plus.camera。
关于该方法的参数说明:
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
count | Number | 否 | 最多可以选择的图片张数,默认9 | 见下方说明 |
sizeType | Array<String> | 否 | original 原图,compressed 压缩图,默认二者都有 | App、微信小程序、支付宝小程序、百度小程序 |
extension | Array<String> | 否 | 根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。 | H5(HBuilder X2.9.9+) |
sourceType | Array<String> | 否 | album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项 | |
crop | Object | 否 | 图像裁剪参数,设置后 sizeType 失效 | App 3.1.19+ |
success | Function | 是 | 成功则返回图片的本地文件路径列表 tempFilePaths | |
fail | Function | 否 | 接口调用失败的回调函数 | 小程序、App |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
下面是 uni.chooseImage() 方法的使用示例:
uni.chooseImage({
count: 1, // 最多可以选择的图片张数,默认为9
sizeType: ['original', 'compressed'], // 可以指定原图或压缩图,默认为['original', 'compressed']
sourceType: ['album', 'camera'], // 可以指定图片来源是相册还是相机,默认为['album', 'camera']
// 选择图片成功
success: function (res) {
// 关于 tempFilePaths 在下文会介绍其注意事项
var tempFilePaths = res.tempFilePaths;
// 在这里可以对选择的图片进行处理,比如显示、上传等操作
console.log('选择的图片路径:', tempFilePaths);
},
// 选择图片失败
fail: function (err) {
console.log('选择图片失败:', err.errMsg);
}
});
在上述代码中,通过调用 uni.chooseImage() 方法,可以打开图片选择界面。可以通过设置 count 来指定最多选择的图片张数,sizeType 来指定选择的图片类型(原图或压缩图),sourceType 来指定图片来源(相册或相机)。
选择成功后,success 回调函数会被调用,可以在回调函数中获取选择的图片的临时文件路径(tempFilePaths)。在回调函数中,可以对选择的图片进行进一步处理,比如显示到页面上、上传到服务器等操作。如果选择图片失败,fail 回调函数会被调用,可以在回调函数中处理错误信息。
?注意:文件的临时路径,在应用本次启动期间可以正常使用,如需持久保存,需在主动调用 uni.saveFile,在应用下次启动时才能访问得到。success 返回参数说明:
参数名 | 类型 | 说明 |
---|---|---|
tempFilePaths | Array<String> | 图片的本地文件路径列表 |
tempFiles | Array<Object>、Array<File> | 图片的本地文件列表,每一项是一个 File 对象 |
关于其他详细的知识点和使用方法可以到 uni-app 官网查看,比如说这个 Tips 还是非常有用,需要的读者到官网(https://uniapp.dcloud.net.cn/api/media/image.html#chooseimage)查阅。
uni.chooseMedia() 是 uniapp 框架提供的一个 API,用于从本地相册或相机选择图片或视频。 使用该方法可以打开系统的图片/视频选择界面,让用户选择一张或多张图片或一个视频。选择完成后,可以获取到选择的图片/视频的临时文件路径。(兼容性如下图)
关于该方法的参数说明:
参数名 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
count | Number | 9(注意:ios不可大于9) | 否 | 最多可以选择的文件个数 |
mediaType | Array<string> | [‘image’, ‘video’] | 否 | 文件类型 |
sourceType | Array<string> | [‘album’, ‘camera’] | 否 | 图片和视频选择的来源 |
maxDuration | Number | 10 | 否 | 拍摄视频最长拍摄时间,单位秒。时间范围为 3s 至 30s 之间 |
sizeType | Array<string> | [‘original’, ‘compressed’] | 否 | 仅对 mediaType 为 image 时有效,是否压缩所选文件 |
camera | String | ‘back’ | 否 | 仅在 sourceType 为 camera 时生效,使用前置或后置摄像头 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
下面是 uni.chooseMedia() 方法的使用示例:
uni.chooseMedia({
count: 1, // 最多可以选择的图片或视频数量,默认为9
mediaType: ['image', 'video'], // 可以指定选择的媒体类型为图片或视频,默认为['image', 'video']
sourceType: ['album', 'camera'], // 可以指定图片/视频来源是相册还是相机,默认为['album', 'camera']
maxDuration: 10, // 指定选择的视频的最大时长,单位秒,默认为60秒
success: function (res) {
// 关于 tempFilePaths 跟上文的注意事项类似
var tempFiles = res.tempFiles;
// 在这里可以对选择的图片或视频进行处理,比如显示、上传等操作
console.log('选择的图片/视频路径:', tempFiles);
},
fail: function (err) {
console.log('选择图片/视频失败:', err.errMsg);
}
});
在上述代码中,通过调用 uni.chooseMedia() 方法,可以打开图片/视频选择界面。可以通过设置 count 来指定最多选择的图片或视频数量,mediaType 来指定选择的媒体类型(图片或视频),sourceType 来指定图片/视频来源(相册或相机),maxDuration 来指定选择的视频的最大时长。(具体使用方法和参数可以移步到官网查询和学习使用)
选择成功后,success 回调函数会被调用,可以在回调函数中获取选择的图片/视频的临时文件路径(tempFiles)。在回调函数中,可以对选择的图片/视频进行进一步处理,比如显示到页面上、上传到服务器等操作。如果选择图片或视频失败,fail 回调函数会被调用,可以在回调函数中处理错误信息。
注意看下面这个图的红框部分,在微信小程序基础库 2.21.0 版本开始, wx.chooseImage 停止维护了,因此在开发过程中,我们在选择上传图片的方法时,需要留意下停止维护是否会影响到项目的后期迭代更新。因此可以使用 uni.chooseMedia 代替,以获得更好的兼容性和功能支持。
二者区别:
除了上面两个方法,这里还有一个方法也可以做到上传图片,但是不建议优先考虑使用 uni.chooseFile() 这个方法来进行上传图片的操作。因为 uni.chooseFile() 是 uniapp 框架提供的一个 API(仅兼容 H5),用于从本地选择文件。 该 API 主要用于选择非媒体文件,如果选择的文件是媒体文件,则可以用另外的专用API(如图片选择、视频选择、多媒体文件选择,含图片视频)。(兼容性如下图)
关于该方法的参数说明:
参数名 | 类型 | 默认值 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
count | Number | 100 | 否 | 最多可以选择的文件数量 | 不同平台的最大值可能会有差异 |
type | String | ‘all’ | 否 | 所选的文件的类型 | 不同平台支持的文件类型可能会有差异 |
extension | Array<String> | 否 | 根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。 | 不同平台可能对拓展名的支持有差异 | |
sourceType | Array<String> | [‘album’,‘camera’] | 否 | (仅在type为image或video时可用)album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项 | 不同平台可能对相册和相机的支持有差异 |
success | Function | 是 | 成功则返回图片的本地文件路径列表 tempFilePaths | ||
fail | Function | 否 | 接口调用失败的回调函数 | ||
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
下面是 uni.chooseFile() 方法的使用示例:
uni.chooseFile({
count: 1, // 最多可以选择的文件数量,默认为1
type: 'all', // 可以指定选择的文件类型,如:image/video/audio/file,也可以使用 all,表示所有文件类型都可以选择,默认为 all
success: function (res) {
var tempFilePaths = res.tempFilePaths;
// 在这里可以对选择的文件进行处理,比如上传等操作
console.log('选择的文件路径:', tempFilePaths);
},
fail: function (err) {
console.log('选择文件失败:', err.errMsg);
}
});
在上述代码中,通过调用 uni.chooseFile() 方法,可以打开文件选择界面。可以通过设置 count 来指定最多选择的文件数量,type 来指定选择的文件类型。
选择成功后,success 回调函数会被调用,可以在回调函数中获取选择的文件的临时文件路径(tempFilePaths)。在回调函数中,可以对选择的文件进行进一步处理,比如上传到服务器等操作。如果选择文件失败,fail 回调函数会被调用,可以在回调函数中处理错误信息。
上面介绍完上传图片的功能和使用案例,我们可以接着思考,既然我们要上传图片到程序或后台,那么上传图片就要读取到用户的手机相册或电脑的文件夹(编译器调试情况下或 PC 端打开小程序),这里就涉及到了一个隐私的问题,因此接下来我们一起来看一下关于小程序隐私保护指引设置,首先通过我的实际例子来给大家分享一下我从出现问题到解决问题的过程。
说到这点,其实也算是对个人 23 年接手的这一个项目做一个技术总结和经验分享吧,在微信官方更新小程序隐私保护指引设置的这个公告之前,小程序中的上传图片功能是正常的,但是在某一天,客户反馈说在注册过程中无法上传图片,因此针对这个问题,提出了三个排查方向,第一是前端上传图片类型错误了,导致前端判断逻辑有误、第二是后端接口的问题,第三是 API 的问题。逐一排查后,发现都不是这个问题,于是重点排查了 API 的问题,我通过输出 API 上传失败的原因和 fail 函数的输出来看,发现无论是在真机调试还是编译器上传都会出现这个报错。报错为:chooseImage:fail api scope is not declared in the privacy agreement,意思就是隐私协议中未声明 fail-api 作用域。
接下来对症下药,针对这个报错找解决方案即可,通过资料搜索和官网查询,发现也有不少开发者也同时遇到了这个问题,说明不是无缘无故冒出来的 bug,因此断定为官网修改 API 或发布新规则所导致。到该小程序的后台消息一看,发现新发布了一条关于小程序隐私保护指引设置的公告,公告这样说到:“为规范开发者的用户个人信息处理行为,保障用户的合法权益,自2023年9月15日起,对于涉及处理用户个人信息的小程序开发者,微信要求,仅当开发者主动向平台同步用户已阅读并同意了小程序的隐私保护指引等信息处理规则后,方可调用微信提供的隐私接口。”
知道了问题所在和微信官方给出的公告说明之后,我们可以很快的针对性的去解决这个问题,接下来分享一下解决方法。
首先我要到该小程序的后台提交协议信息,步骤为:进入首页,点击左侧导航栏的设置 => 功能设置 => 用户隐私保护指引设置 => 去填写信息提交审核。具体如下图。
这里我们可以勾选“选中的照片或视频”这个选项(上传图片所需),其他则根据实际项目需要勾选即可。只有在指引中声明所处理的用户个人信息,才可以调用平台提供的对应接口或组件。若未声明,对应接口或组件将无法调用成功。
除此之外还可以配置用户隐私授权弹窗,微信提供了 wx.onNeedPrivacyAuthorization(function callback) 接口,意为用户触发了一个微信侧未记录过同意的隐私接口调用,开发者可通过响应该事件选择提示用户的时机。此外,微信还提供了 wx.requirePrivacyAuthorize(Object object) 接口,可用于模拟触发 onNeedPrivacyAuthorization 事件。仅有在指引中声明所处理的用户个人信息,才可以调用平台提供的对应接口或组件。若未声明,对应接口或组件将直接禁用。
如要进行代码提审,开发者需先自行声明是否有采集用户隐私,如有,则需在提审页面-「用户隐私保护设置」选择“采集用户隐私”。
通过上面一系列的方法,我也是解决这次项目出现的问题了,亲测有效,审核通过之后,稍等片刻,项目重新编译就好了。这次发现问题解决问题的经验是非常宝贵的,通过这次项目的事故也让我在开发的过程中更加仔细了,除此之外我也会时刻关注微信官方发布的最新规则和公告等等,避免出现影响项目正常运行的情况,如果是迫不得已也要预留好解决方案和备用方案。
到此就是本篇文章的全部内容了,这篇文章记录的主要内容是微信小程序的上传图片功能选择和使用对比以及小程序隐私保护指引设置。回顾 2023年,我开始接触了 uni-app 和微信小程序的开发,在开发和学习的过程中,我遇到了很多问题和挑战,同时也积累了很多实战技巧和经验,这篇文章是博主 uni-app 专栏第一篇年度实战总结的文章,后续还会不断的更新更多关于 uni-app 的干货、实战经验、学习经验,期待你的关注和留言。