[从入门到入土(前端篇)]五,上传文件到OSS(一)
这几天呢,公司要开发小程序,我忙着搞小程序去了,所以就没有更新,如果有期待后面文章的同学,这里我说一声抱歉久等啦~
什么是OSS
OSS叫对象存储.按照我的理解,就是一个云资源管理器.详细介绍可以见官网,我这里不阐述.
为什么要上传文件到OSS呢?
首先呢,这是一个博客网站,里面有非常多的图片(包括展示图,博客内容中的图片),还有记录内容的md文件,如果全部放在服务器上,那么每看一篇文章,前端会产生很多次资源访问,会占用大量的带宽,导致访问速度变慢.
然后呢,垃圾程序员木有软妹币,服务器选择的是最垃的配置,所以…
选择上传方式
上传文件到OSS有很多方式,比如前端直传,后端直传,后端签名前端直传.
前端直传不安全,后端直传需要将文件发送到后端再上传,麻烦
所以我们采用一种安全,方便的形式:后端进行加密签名,前端进行上传文件
GameStart
OSS准备
1.新建Bucket
2.获取AccessKeyId和secret
在首页点击AccessKeyId 跳转页面获取值
创建key (这里需要手机验证)
将获取到的两个值,交给后端处理
后端准备 后端代码 码云地址:blogServerDemo
我的网站后端用的nodejs,如果其他语言的代码,可上阿里云文档中查找
后端准备一个ossSign接口,进行签名加密,直接贴代码
const crypto = require('crypto');
const ossConfig={
OSSAccessKeyId: '', //从oss获取的ID
secret: '', //id对应的secret
host: '',//oss地址
expAfter: 300000, // 签名失效时间,毫秒
maxSize: 1048576000, // 文件最大的 size
}
/**
* 前端直传获取前端签名
* @param ctx
* @param next
* @returns {Promise<void>}
*/
async function ossSign(ctx,next){
const dirPath = 'demo/'; // bucket 项目里的文件路径
const host = ossConfig.host;
const expireTime = new Date().getTime() + ossConfig.expAfter;
const expiration = new Date(expireTime).toISOString();
const policyString = JSON.stringify({
expiration,
conditions: [
[ 'content-length-range', 0, ossConfig.maxSize ],
],
});
const policy = Buffer.from(policyString).toString('base64');
const signature = crypto.createHmac('sha1', ossConfig.secret).update(policy).digest('base64');
ctx.body = {
code:200,
data:{
signature,
policy,
host,
OSSAccessKeyId: ossConfig.OSSAccessKeyId,
key: expireTime,
startsWith: dirPath,
}
}
}
module.exports={
ossSign,
}
这时候后端返回参数交给前端上传OSS
前端准备
1.随便写一个上传界面,我就复制element-plus的上传接口进行测试(详细代码见项目地址)
2.api文件中新建oss接口
import http from "../../utils/http"
/**
* get访问测试
* @param params
* @returns {Promise | Promise<unknown>}
*/
export const ossSign=(params)=>{
return http.post("/ossSign",params);
}
3. 在选择完文件后(upLoad方法中调用接口,获取参数)
4.通过后台提供的参数 进行前端直传
在 oss api中,新建一个上传方法
import axios from "axios";
/**
* 前端直传oss
* @param file
* @param ossInfo
*/
export const ossUpload=(file,ossInfo)=>{
const files = file
const point = files.name.lastIndexOf('.')
const suffix = files.name.substr(point) // 获取文件后缀名
const fileName = ossInfo.key + suffix
let param = new FormData() // 创建form对象
param.append('OSSAccessKeyId', ossInfo.OSSAccessKeyId)
param.append('policy', ossInfo.policy)
param.append('key', ossInfo.startsWith + fileName)
param.append('success_action_status', 200)
param.append('signature', ossInfo.signature)
param.append('file', files, fileName)
let config = {
headers: {'Content-Type': 'multipart/form-data'}
}
// 添加请求头
return new Promise((res,rej)=>{
axios.post(ossInfo.host, param, config)
.then(response => {
console.log(response)
if(response.status == 200){
console.log('上传成功')
res(response)
}else{
rej(response);
}
})
})
// return http.post("/admin/login",params);
}
将选择的文件以及后端签名后的参数,调用参数
...
// 上传图片
upLoad (file) {
let that = this;
console.log(file);
ossSign({}).then((res)=>{
console.log(res);
if(res.code == 200){
let ossInfo = res.data;
let fileName = file.file.name;
let suffix = fileName.substr(fileName.lastIndexOf('.'))
ossUpload(file.file,ossInfo).then((res)=>{
that.url= `${ossInfo.host}/${ossInfo.startsWith}${ossInfo.key}${suffix}`//拼接完整的OSS地址
})
}
})
}
...
5.查看效果
前端效果
哦豁,出现跨域问题,不用担心
处理上传oss文件跨域
我们打开OSS控制台,点击Bucket的权限管理->跨域设置->创建规则
重新尝试
Bingo 上传成功!!!!
看看oss