图片的上传
# 一、从本地获取图片
uni-app
提供了 uni.chooseImage(OBJECT)
接口,用于从本地相册选择图片或使用相机拍照。在一些平台上(如微信小程序)官方建议使用 uni.chooseMedia
,但为兼容大多数场景,本示例仍以 uni.chooseImage
进行介绍。
# 1.1 基本用法
示例代码:
uni.chooseImage({
count: 3, // 可选最多图片数,默认9
sizeType: ['original', 'compressed'], // original: 原图, compressed: 压缩图
sourceType: ['album', 'camera'], // 可通过相册或相机获取
success: (res) => {
console.log('成功获取图片:', res.tempFilePaths);
},
fail: (err) => {
console.error('获取图片失败:', err);
}
});
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
参数说明
- count (Number):最多可选多少张图片,默认为 9。注意在 H5 平台可能无法严格限制数量,具体依赖浏览器实现。
- sizeType (Array
<String>
):可选'original'
(原图)或'compressed'
(压缩图),默认同时存在。 - sourceType (Array
<String>
):可选'album'
(相册)或'camera'
(相机),默认同时存在。如果只想直接打开相机,可仅传['camera']
。 - crop (Object):在 App 端可设置图像裁剪参数(需 App 3.1.19+),如裁剪宽高和质量。若设置此项,则
sizeType
失效。 - success (Function):成功回调,返回
res
对象,包含tempFilePaths
(图片本地路径数组)和tempFiles
(包含更多信息的文件对象数组)。 - fail (Function):失败回调。
- complete (Function):无论成功或失败都会执行的回调函数。
Tips:
- 在微信小程序 2.21.0+ 版本,官方建议使用
uni.chooseMedia
替代uni.chooseImage
。 - H5 平台对于相册和摄像头的支持因浏览器差异而异,限制功能可能不完全生效。
- App 端如需更多拍照功能(切换前后摄像头等),可参考
plus.camera
。
# 1.2 获取到的返回值
- tempFilePaths:一个字符串数组,每一项是图片在本地的临时路径。
- tempFiles:一个对象数组,每一项包含
path
(本地路径)、size
(文件大小,单位 B)、name
(文件名,H5 支持)和type
(文件类型,H5 支持)等。
示例回调结构(简化):
{
tempFilePaths: [ "/path/to/image1.jpg", "/path/to/image2.png" ],
tempFiles: [
{
path: "/path/to/image1.jpg",
size: 12345,
name: "image1.jpg",
type: "image/jpeg"
},
{
path: "/path/to/image2.png",
size: 23456,
name: "image2.png",
type: "image/png"
}
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1.3 在页面上展示本地图片
若要在页面中预览所选图片,可将获取的 tempFilePaths
数组保存到 data 中并使用 <image>
标签绑定路径。示例:
<template>
<view>
<button @click="chooseImages">选择图片</button>
<view v-for="(item, index) in images" :key="index">
<image :src="item" style="width: 100px; height: 100px;" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
images: []
};
},
methods: {
chooseImages() {
uni.chooseImage({
count: 3,
success: (res) => {
// 将tempFilePaths中的路径加入images数组
this.images.push(...res.tempFilePaths);
}
});
}
}
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
以上仅完成了本地图片选择和预览,并没有进行真正的上传操作。
# 二、将图片上传至服务器
要实现完整的上传功能,需要与后端服务器接口或云服务交互,通常使用 uni.uploadFile(OBJECT)
方法发送文件。
# 2.1 uni.uploadFile
的基本用法
示例代码:
uni.uploadFile({
url: 'https://example.com/upload', // 服务端接收上传的地址
filePath: localImagePath, // 本地文件路径
name: 'file', // 后端用来识别文件的字段名
formData: {
userId: 123 // 额外表单数据
},
success: (uploadRes) => {
console.log('上传成功:', uploadRes.data);
},
fail: (err) => {
console.error('上传失败:', err);
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
参数说明
- url (String):服务器接收上传的 URL。
- filePath (String):要上传的文件本地路径,通常来自
chooseImage
返回的tempFilePaths
。 - name (String):后端用来识别文件的字段名,例如后端可能通过
request.files['file']
获取。 - formData (Object):可在上传表单中附加一些额外字段,如用户 ID、token 等。
- success / fail / complete:请求完成后的回调函数。
注:uni.uploadFile
底层是以 multipart/form-data
格式将文件发送到服务器,后端需能正确处理此格式。
# 2.2 在页面中上传案例
综合“选择图片”与“上传文件”,可写成如下示例:
<template>
<view>
<button @click="chooseImages">选择图片</button>
<button @click="uploadAll">上传所有图片</button>
<view v-for="(item, index) in images" :key="index">
<image :src="item" style="width: 100px; height: 100px;" />
<text>{{ uploadStatus[index] }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
images: [], // 存放选择的本地图片路径
uploadStatus: [] // 存放每张图片的上传状态
};
},
methods: {
chooseImages() {
uni.chooseImage({
count: 3,
success: (res) => {
// 将本地图片路径加入images数组
this.images.push(...res.tempFilePaths);
// 初始状态设为“未上传”
res.tempFilePaths.forEach(() => this.uploadStatus.push('未上传'));
}
});
},
uploadAll() {
// 遍历 images 数组,依次上传
this.images.forEach((filePath, index) => {
this.uploadSingle(filePath, index);
});
},
uploadSingle(filePath, idx) {
this.uploadStatus[idx] = '上传中...';
uni.uploadFile({
url: 'https://example.com/api/upload', // 后端上传地址
filePath,
name: 'file',
formData: {
userId: 123
},
success: (res) => {
// 后端返回的结果一般是字符串,需要自行解析
const data = JSON.parse(res.data);
if (data.code === 200) {
this.uploadStatus[idx] = '上传成功';
} else {
this.uploadStatus[idx] = '上传失败';
}
},
fail: (err) => {
this.uploadStatus[idx] = '上传失败';
console.error('上传出错:', err);
}
});
}
}
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
说明:
- 用户先点击“选择图片”,将返回的
tempFilePaths
存入images
数组。 - “上传所有图片”按钮触发时,遍历
images
并调用uploadSingle
。 uploadFile
成功后,需要解析后端返回的 JSON 数据(通常包含状态码、上传后的文件 URL 等)。- 根据后端返回的结果,为对应图片更新上传状态(如“上传成功”或“上传失败”)。
# 2.3 进阶功能
上传进度:
uni.uploadFile
在微信小程序端或 App 端,可通过监听上传任务对象的进度事件来获取上传进度。具体可参考官方文档中uploadTask.onProgressUpdate
。- 在 H5 或其它平台可能不完全支持。
并发控制:
- 若一次选择多张图片,若后端或网络带宽限制,可以限制同时上传的数量。例如设置最大并发数为 2,每完成一个再上传下一个。
分片上传:
- 当图片体积较大(几十MB或更大),或网络不稳定时,为确保成功可考虑分片上传。此时需前端和后端配合实现。
云存储:
- 如果使用 UniCloud 或其他云服务,可查看对应的云函数或云存储 API,以获取内置的上传方式。
# 三、注意事项和小结
临时路径有效期:
- 在小程序/App 环境下,
tempFilePaths
通常只在当前应用生命周期内有效。如果下次启动依然需要访问,则需要调用uni.saveFile
将其转存到本地存储目录。
- 在小程序/App 环境下,
平台差异:
- H5 平台对
count
、sourceType
等限制可能不生效,具体取决于浏览器支持程度。 - 微信小程序官方在较新版本已停止维护
chooseImage
,推荐使用chooseMedia
,uni-app
也有相应接口以兼容多端。
- H5 平台对
后端接口:
- 确保后端能够正确处理
multipart/form-data
格式(或其它你所使用的格式如 Base64)。 - 通常后端会返回一个包含状态码、消息、文件URL的 JSON。前端解析后判断是否上传成功。
- 确保后端能够正确处理
权限授权:
- 在 iOS/Android 上,首次调取相册或相机可能需要用户授权;
- 在微信小程序/支付宝小程序/百度小程序等,需要在平台后台配置合法域名和权限,否则可能报错或无法使用相机。
选取其他类型文件:
- 选择 doc、pdf、zip 等非媒体文件时,
chooseImage
不可行。可考虑使用uniapp
插件市场的“文件选择”插件,或根据平台文档调用相应接口(如微信小程序wx.chooseMessageFile
,App 端可用 Native 功能等)。
- 选择 doc、pdf、zip 等非媒体文件时,
综上所述,要完成在 uni-app
中图片选择与上传的流程,核心流程是:
- 调用
uni.chooseImage
选取本地图片; - 获取到临时文件路径
tempFilePaths
; - 使用
uni.uploadFile
逐个将图片提交给后端。
编辑此页 (opens new window)
上次更新: 2025/02/01, 02:18:15