阿里云oss实现服务端签名上传/下载(nodejs)

1,069 阅读3分钟

前言

移动云毕竟小众,之前客户项目用的移动云,不是很稳定,或者很慢,没办法要切换阿里云,这不今天就开始搞了,也很简单,后端主要就搞两个,一个签名上传,一个签名下载查看,为了兼容之前项目的数据结构返回样式都类似(这里只改了一个上传参数名字,你猜哪一个)

花费了两个小时终于看文档带测通了,不愧是很多人在用的,对接就是快,好了话不多说,直接开讲

ali-oss 库

对接阿里云肯定要用到他的库 ali-oss阿里云github文档地址

yarn add ali-oss

安装完毕之后,我们直接就开始操作了

使用 ali-oss 对接 OSS

千篇一律的申请key相关,打开阿里云相关页面,进入控制台,找 对象储存OSS,在里面创建我们的 bucket桶,设置权限(将权限设置私有,里面对自己账号开放权限,我看有人直接公开了,那不别人随便访问了是吧,白签名了😂),这里通过签名方式访问桶内文件,别忘了申请key、secret

开始项目

初始化

导入 ali-oss

const oss = require('ali-oss')

配置 .env 环境变量

OSS_POINT=oss-cn-beijing.aliyuncs.com
OSS_ACCESSKEY=sdssdsdsdlksjdkfhskjdfhksdjf
OSS_SECRETKEY=kasjdkjashdkfjkjsdfasdjkfasdfsafd
OSS_BUCKETNAME=oss-dev

创建 oss client 对象,为什么我要创建一个 static client 呢,单纯是想在 module 下引用时,避免频繁创建罢了

static client: any
host: string

constructor() {
    if (!OSSService.client) {
        OSSService.client = new oss({
            accessKeyId: envConfig.OSS_ACCESSKEY, //key
            accessKeySecret: envConfig.OSS_SECRETKEY, //secret
            bucket: envConfig.OSS_BUCKETNAME, //桶的名字
            endpoint: envConfig.OSS_POINT, //point
            secure: true, // https,默认http,这里设置一下(毕竟小程序需要https)
        })
    }
    //拼接host,upload会用到
    this.host = `https://${envConfig.OSS_BUCKETNAME}.${envConfigfig.OSS_POINT}`
}

签名访问文件

signedUrl(filename: string) {
    return OSSService.client.signatureUrl(filename, {
        expires: 7 * 24 * 3600, //7天
    })
}

签名上传 post formdata

signUpload(filename: string) {
    const date = new Date()
    date.setDate(date.getDate() + 1)
    const res = OSSService.client.calculatePostSignature({
        expiration: date.toISOString(), //1天时间
        conditions: [
            ['content-length-range', 0, 200 * 1024 * 1024], //设置上传文件的大小限制 200m。
        ],
    })
    return {
        url: this.host, //设置host
        formdata: { //设置给前端用的formdata
            key: filename,
            ...res,
        },
    }
}

全部文件

import { Injectable } from '@nestjs/common'
import { envConfig } from 'src/app.config'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const oss = require('ali-oss')

@Injectable()
export class OSSService {
    static client: any
    host: string
    constructor() {
        if (!OSSService.client) {
            OSSService.client = new oss({
                accessKeyId: envConfig.OSS_ACCESSKEY,
                accessKeySecret: envConfig.OSS_SECRETKEY,
                bucket: envConfig.OSS_BUCKETNAME,
                endpoint: envConfig.OSS_POINT,
                secure: true,
            })
        }
        this.host = `https://${envConfig.OSS_BUCKETNAME}.${envConfigfig.OSS_POINT}`
    }

    async signUpload(filename: string) {
        const date = new Date()
        date.setDate(date.getDate() + 1)
        const res = OSSService.client.calculatePostSignature({
            expiration: date.toISOString(), //1天时间
            conditions: [
                ['content-length-range', 0, 200 * 1024 * 1024], //设置上传文件的大小限制 200m。
            ],
        })
        return {
            url: this.host,
            fields: {
                key: filename,
                ...res,
            },
        }
    }

    signedUrl(filename: string) {
        return OSSService.client.signatureUrl(filename, {
            expires: 7 * 24 * 3600, //7天
        })
    }
}

图片缩放

涉及到图片缩放的,只需要后面加入一些参数即可,甚至是视频头一帧图片,图片可以等比缩放,可以剪裁 参考地址,详细可以看查看这里

//按照宽度500缩放(w、h)
xxx.png?x-oss-process=image/resize,w_500

//按照最大的一边500缩放(l、s)
xxx.png?x-oss-process=image/resize,l_500

m缩放模式(个人感觉 fill、pad应该是用的比较多的吧)
-   lfit(默认值):等比缩放,缩放图限制为指定w与h的矩形内的最大图片。
-   mfit:等比缩放,缩放图为延伸出指定w与h的矩形框外的最小图片。
-   fill:将原图等比缩放为延伸出指定w与h的矩形框外的最小图片,然后将超出的部分进行居中裁剪。
-   pad:将原图缩放为指定w与h的矩形内的最大图片,然后使用指定颜色居中填充空白部分。
-   fixed:固定宽高,强制缩放。 会出现变形

最后

阿里云对接挺简单的,只要用的人多,办法总比困难多,是吧