uniapp调用七牛云api实现文件上传
实现思路:
1.使用node.js向客户端提供uploadToken,客户端获取uploadToken后使用七牛云的api接口发起网络请求,上传文件;
node.js向外提供uploadToken的接口-客户端不用下载七牛云的包和SDK-,拿到uploadToken发起网络请求直接上传文件即可.
2.在本地,直接node.js运行实现的上传.
一、在unicloud云函数实现node.js获取uploadToken,然后向外提供一个接口
1.新建云函数:
2.首先,需要安装qiniu模块。 在终端上输入以下命令进行安装:
npm install qiniu
2.按照官方文档获取 Access Key、Secret Key 和存储空间名称(Bucket)。
在使用七牛云服务之前,你需要登录去七牛云平台开通账号,申请 Access Key、Secret Key,以及创建一个 Bucket。
const qiniu = require('qiniu');
qiniu.conf.ACCESS_KEY = 'Your_Access_Key';
qiniu.conf.SECRET_KEY = 'Your_Secret_Key';
3.创建上传凭证。
Qiniu 中的上传 Token 是在客户端生成,在客户端直接调用 API 上传文件时需要携带该 Token。可以通过七牛云提供的 SDK 自动生成上传凭证。下面是基本的生成方式
const bucket = 'Your_Bucket_Name';
const key = 'Your_File_Name';
const putPolicy = new qiniu.rs.PutPolicy({ scope: `${bucket}:${key}` });
// uploadToken 就是我们需要的token:uploadToken
const uploadToken = putPolicy.uploadToken();
云函数的完整代码如下:
// 示例代码
'use strict';
const qiniu = require('qiniu');
var accessKey = 'Your_Bucket_Name'; // 这里换成自己的accessKey -在七牛云后台有,直接复制过来
var secretKey = 'Your_File_Name'; // 这里换成自己的secretKey -在七牛云后台有,直接复制过来
var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
var options = {
scope: 'xingyue-yuelao', // 必填, 七牛云控制台添加的空间名称
// expires: 7200, // expires非必填, 在不指定上传凭证的有效时间情况下,默认有效期为1个小时。expires单位为秒
returnBody: '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}'
// returnBody非必填, 有时候我们希望能自定义这个返回的JSON格式的内容,可以通过设置returnBody参数来实现。
};
var putPolicy = new qiniu.rs.PutPolicy(options); // 配置
var uploadToken = putPolicy.uploadToken(mac); // 获取上传凭证:uploadToken
// 到这里就成功拿到uploadToken 了,云函数提供一个接口,把这个token返回出去,客户端调用接口获取。
// 当然,为了安全考虑的话,获取这个token最好做安全控制,比如在这里做账号密码验证,调接口的时候传账号密码来,验证通过再返回token,这里就不做演示了。
// 下面是往外提供接口
exports.main = async (event, context) => {
/**
* 调用method:POST
* 无需参数,调用即可获取token,token1小时过期
*/
return {
message: '获取token成功',
status: 'SUCCESS',
uploadToken: uploadToken,
}
};
然后把云函数上传部署后做云函数url化,这样就可以在任意地方调用啦:
做完上面的步骤后,就可以在uniapp调用接口获取token了:
// 发起请求,获取上传文件需要的uploadToken
uni.request({
// url就是上面提供的那个云函数url化后的地址
url: 'https://fc-mp*******next.bspapp.com/getuploadToken',
method: 'POST',
// data: {},
success: (res) => {
// res.data.uploadToken; 就是uploadToken咯
}
})
下面可以在客户端发起网络请求上传文件了:
//选择图片
chooseImage() {
uni.chooseImage({
count: this.rduLength < this.count ? this.rduLength : this.count, //最多可以选择的图片张数,默认9
sizeType: ['original', 'compressed'], //original 原图,compressed 压缩图,默认二者都有
sourceType: ['album', 'camera'], //album 从相册选图,camera 使用相机,默认二者都有
success: res => {
this.useQiniiyun_upload(res.tempFilePaths); // 这个是调用七牛云上传
}
});
},
// files 是文件列表[],多个文件临时地址
useQiniiyun_upload(files) {
// console.log('图片列表files:', files)
uni.showLoading({
title: '图片上传中..',
})
/**
* 参数:
* 1.file:要上传的文件选择器或者文件对象
*2. filename_qn:上传到七牛后保存的文件名。如果不指定,则由七牛服务器自动生成。
*3. token:上传凭证,详见 上传策略
*/
// 上传以后的文件名-存在七牛云的文件名字-空间的域名+文件名就可以访问文件了!最好做时间戳+随机数这样做一个唯一的文件名字
const filename_qn = 'unicloud_' + new Date().getTime() + ('000000' + Math.floor(Math.random() * 999999)).slice(-6) + '.png';
// console.log('上传前生成的文件名字:', filename_qn)
// 发起请求,获取上传文件需要的uploadToken
uni.request({
url: 'https://*********.next.bspapp.com/getuploadToken',
method: 'POST',
// data: {},
success: (res) => {
const token = res.data.uploadToken;
// 获取成功后发起文件上传
/**
* url:我这里是(https://upload-z2.qiniup.com):华南-广东 对应的七牛云的地址-其他的可以自行百度
* filePath:文件本地临时地址,一次只能一个,字符串类型
*/
uni.uploadFile({
url: 'https://upload-z2.qiniup.com',
filePath: files[0],
name: 'file',
formData: {
'key': filename_qn, // 存到七牛云后的文件名字,访问图片会用到
'token': token, // uploadToken,需要动态获取,调用云函数接口获取
},
// 存成功后的回调
success: (uploadFileRes) => {
let key = JSON.parse(uploadFileRes.data).key;
// 空间绑定的域名(在七牛云配置)+key就是文件的访问地址
const img_url = 'https://yuelao.yhxweb.top/' + key
// this.$util.msg('图片上传成功了');
uni.hideLoading();
// 删除数组的第一项地址,再调用,直到上传完所有文件
files.shift();
if (files.length > 0) {
this.useQiniiyun_upload(files);
}
},
fail: (err) => {
console.log('上传失败了', err);
uni.hideLoading();
}
});
}
})
},
实现演示,上传成功啦:
去七牛云看看,没问题了:
下面是在本地测试时候,直接node.js运行实现的上传,全部代码如下:
文件结构:
npm安装七牛云包,在最上面有.
全部代码:
'use strict';
const qiniu = require('qiniu');
var accessKey = 'RI*********ycN9';// Your_Bucket_Name
var secretKey = 'LVU***********zQNU4P9'; // Your_File_Name
var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
var options = {
scope: 'xingyue-yuelao', // 必填, 七牛云控制台添加的空间名称
// expires: 7200, // expires非必填, 在不指定上传凭证的有效时间情况下,默认有效期为1个小时。expires单位为秒
returnBody: '{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}'
// returnBody非必填, 有时候我们希望能自定义这个返回的JSON格式的内容,可以通过设置returnBody参数来实现。
};
var putPolicy = new qiniu.rs.PutPolicy(options); // 配置
var uploadToken = putPolicy.uploadToken(mac); // 获取上传凭证
var config = new qiniu.conf.Config();
// 空间对应的机房
config.zone = qiniu.zone.Zone_z2;
// 是否使用https域名
config.useHttpsDomain = true;
// 上传是否使用cdn加速
config.useCdnDomain = true;
var formUploader = new qiniu.form_up.FormUploader(config);
// formUploader.putFile方法上传文件
// 第一个属性为上传凭证
// 第二个属性为上传文件要以什么命名 null 则随机命名
// 第三个为文件的相对地址, 相对为当前执行文件的地址
// 第四个属性putExtra, 应该是额外需要的参数,用new qiniu.form_up.PutExtra()获取
// 第五个为回调函数,respErr失败内容 respBody主体内容 respInfo信息内容
var putExtra = new qiniu.form_up.PutExtra();
// 上传以后的文件名
const filename = 'node' + new Date().getTime() + ('000000' + Math.floor(Math.random() * 999999)).slice(-6) + '.png';
// 文件根路径的地址-文件空间绑定的域名
const BaseUrl = 'https://yuelao.yhxweb.top/';
// 上传成功后的返回值
let resdata = null;
formUploader.putFile(uploadToken, filename, './img/1.png', putExtra, function (respErr, respBody, respInfo) {
if (respErr) {
throw respErr;
}
if (respInfo.statusCode == 200) {
// 如果成功,这里内容便是 图片信息
resdata = {
url: BaseUrl + respBody.key,
fsize: respBody.fsize,
}
console.log('上传成功啦!',resdata);
} else {
console.log(respInfo.statusCode);
console.log(respBody);
console.log('出错了', respBody)
}
});
console.log('上传成功啦!',resdata);
运行后:
可以看到上传成功啦: