uniapp调用七牛云api实现文件上传-node.js向外提供uploadToken的接口-客户端不用下载七牛云的包和SDK-发起网络请求直接上传(外加vue3+vantz组件库实现上传)

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);

运行后:在这里插入图片描述
可以看到上传成功啦:
在这里插入图片描述

vue3web端在已有token的情况下,发起网络请求直接上传文件到七牛云:

vue3通过vant组件库拿到文件流上传到七牛云
获取token的接口这边是通过node提供的接口。

<template>
  <div class="image-upload">
    <van-uploader class="a-left avatar-wrapper"
                  v-model="fileList"
                  :multiple="true"
                  :max-count="uploadNum"
                  :after-read="afterRead0">
      <van-image width="80px"
                 height="80px"
                 fit="cover"
                 v-show="fileList.length < uploadNum"
                 :src="avatarUrl0" />
      <template #preview-cover="{ file }">
        <div class="preview-cover van-ellipsis">{
    
    {
    
     file.name }}</div>
      </template>
    </van-uploader>
  </div>
</template>

<script setup>
import {
    
     defineEmits, defineProps } from 'vue'
import {
    
     ref } from 'vue'
import {
    
     getQiNiuYunToken } from '@/api/common'
import axios from 'axios'
const props = defineProps({
    
    
  value: {
    
    
    type: String,
    default: ''
  },
  // 允许上传的最大数量
  uploadNum: {
    
    
    type: Number,
    default: 4
  }
})

// 上传图片按钮的背景图片
const avatarUrl0 = ref('https://yuelao.yhxweb.top/yuelaoVue3/bj.png')

// 已上传的图片列表
const fileList = ref([])

// 图片选择后的回调
const afterRead0 = async (file) => {
    
    
  // 获取七牛云token
  const {
    
     data: qiniuyun_token } = await getQiNiuYunToken()
  if (qiniuyun_token) {
    
    
    // 拿到token后,将图片上传至七牛云
    console.log('七牛云token:', qiniuyun_token)
    if (file.forEach) {
    
    
      // 一次上传多个文件
      file.forEach(fileItem => {
    
    
        useQiniiyun_upload(fileItem, qiniuyun_token)
      });
    } else {
    
    
      // 一次上传一个文件
      useQiniiyun_upload(file, qiniuyun_token)
    }
  }
}

/**
 * 调用七牛云接口
 * @param {*} files 图片列表
 * @param {*} qiniuyun_token 七牛云token
 */
const useQiniiyun_upload = (file, qiniuyun_token) => {
    
    
  /**
    * 参数:
    * 1.file:要上传的文件选择器或者文件对象
    *2. filename_qn:上传到七牛后保存的文件名。如果不指定,则由七牛服务器自动生成。
    *3. token(qiniuyun_token):上传凭证,详见 上传策略
    */
  // 上传以后的文件名-存在七牛云的文件名字-空间的域名+文件名就可以访问文件了!最好做时间戳+随机数这样做一个唯一的文件名字
  const filename_qn = 'yuelaoVue3_' + new Date().getTime() + ('000000' + Math.floor(Math.random() * 999999)).slice(-6) + file.file.name;
  // console.log('上传前生成的文件名字:', filename_qn)
  // 创建FormData对象,用于上传文件
  const formData = new FormData();
  // formData.append('x:type','image/png');
  formData.append('x:type', file.file.type); // 文件类型
  formData.append('file', file.file); // 添加文件流(一定要写file.file 不然上传了文件打不开!!!!)
  formData.append('key', filename_qn); // 添加文件名
  /**
    * uploadUrl:我这里是(https://upload-z2.qiniup.com):华南-广东 对应的七牛云的地址-其他的可以自行百度
    */
  const uploadUrl = 'https://upload-z2.qiniup.com'
  const options = {
    
    
    headers: {
    
    
      'Content-Type': 'multipart/form-data'
    },
    params: {
    
    
      token: qiniuyun_token,
    }
  }
  // 发起POST请求,上传文件
  axios.post(uploadUrl, formData, options).then(response => {
    
    
    console.log('response.data', response.data)
    console.log('response.data', 'https://yuelao.yhxweb.top/' + response.data.key) // 上传后的图片路径
  }).catch(error => {
    
    
    console.log('error', error)
  })
}

</script>

<style lang="less" scoped>
.preview-cover {
    
    
  position: absolute;
  bottom: 0;
  box-sizing: border-box;
  width: 100%;
  padding: 4px;
  color: #fff;
  font-size: 12px;
  text-align: center;
  background: rgba(0, 0, 0, 0.3);
}
</style>

效果
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_61950936/article/details/130312312