文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

基于服务端怎么实现OSS文件直传

2023-07-02 08:41

关注

这篇文章主要介绍“基于服务端怎么实现OSS文件直传”,在日常操作中,相信很多人在基于服务端怎么实现OSS文件直传问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”基于服务端怎么实现OSS文件直传”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

优缺点

从“客户端 — 服务器 — OSS”的传输模式,变更为“客户端 — OSS”的模式,最大的好处是,省掉了上传服务器的这一步,上传效率更高,速度更快(相比较于一般服务器的带宽,可以认为 OSS 的宽带是“几乎无限”的)。

当然该模式也有缺点,那就是增加了很多额外的开发工作量,主要包含 2 部分:

(1)服务端增加生成上传 OSS 凭证的代码。

(2)客户端增加从服务端获取上传 OSS 凭证的代码和对直传 OSS 进行适配。

整体而言,直传模式除了增加一点开发工作量以外,从架构层面,几乎没有任何缺点。

流程

实际上,整个流程非常简单,包含了两步:

(1)客户端向服务端发送请求,获取直传 OSS 的凭证。

(2)客户端向 OSS 上传文件,并携带该凭证。

逻辑拆解

整个“生成上传 OSS 凭证”过程,实际上做了这么几件事:

(1)上传凭证鉴权由 policy 提供,根据私密配置生成这个 policy

(2)由于上传环节脱离了开发者服务器,因此你可以在 policy 中定义各种限制,例如上传最大体积、文件名等。

(3)将 policy 转化为指定的格式。

代码实现

我们先考虑将流程的每一步实现,然后再将流程代码封装成函数。

OSS 配置

首先定义 OSS 的配置文件,关于配置项的内容,可以参考文档:help.aliyun.com/document_de…

const ossConfig = {  bucket: 'xxxxxxxx',  accessKeyId: 'xxxxxxxx',  accessKeySecret: 'xxxxxxxx',    url: 'xxxxxxxx',}

policy 内容

对于 policy ,有很多配置项,我们先考虑生成“写死”的模式,然后再优化为由函数参数传入配置项。以下是一个最基础的 policy

有效期

首先定义一个有效时长(单位:毫秒),然后该凭证的有效截止时间则为“当前时间 + 有效时长”,最后需要转化为 ISO 时间字符串格式。

const timeout = 4 * 60 * 60 * 1000const expiration = new Date(Date.now() + timeout).toISOString()

文件名

文件名建议使用 UUID(笔者习惯性使用去掉短横线的 UUID),避免重复。

import { v4 as uuidv4 } from 'uuid'const filename = uuidv4().replace(/-/gu, '')

一般建议按照不同的业务模块,将文件划分不同的目录,例如这里使用 file 目录,那么完整的 OSS 文件路径则为:

const dirname = 'file'const key = dirname + '/' + filename

需要注意的是,文件路径不能以 “/” 开头(OSS 本身的要求)。

将以上内容整合,就形成了 policy 文本,以下是一个基础格式:

const policyText = {  expiration: expiration,  conditions: [    ['eq', '$bucket', ossConfig.bucket],    ['eq', '$key', key],  ],}

转化 policy

policyText 转化为 Base64 格式后,就是要求的 policy 了。

// 将 policyText 转化为 Base64 格式const policy = Buffer.from(JSON.stringify(policyText)).toString('base64')

然后对 policy 使用 OSS 密钥使用 HmacSha1 算法签名签名。

import * as crypto from 'crypto'// 使用 HmacSha1 算法签名const signature = crypto.createHmac('sha1', ossConfig.accessKeySecret).update(policy, 'utf8').digest('base64')

最后将上述流程中的相关字段返回给客户端,即为“上传凭证”。

进一步分析

以上完整演示了整个流程,我们进一步分析,如何将其封装为一个通用性的函数。

(1)凭证的有效时长可以根据不同的业务模块分别定义,于是做成函数配置项。

(2)目录名称也可以做成配置项。

(3) policy 还有更多的配置内容,可以抽取一部分做成配置项,例如“允许上传的最大体积”。

完整代码

以下是封装为“服务”的使用 Nest.js Web 框架的相关代码,供参考。

import { Injectable } from '@nestjs/common'import * as crypto from 'crypto'import { v4 as uuidv4 } from 'uuid'export interface GenerateClientTokenConfig {    dirname: string    expiration?: number    maxSize?: number}export interface ClientToken {  key: string  policy: string  signature: string  OSSAccessKeyId: string  url: string}export interface OssConfig {  bucket: string  accessKeyId: string  accessKeySecret: string  url: string}@Injectable()export class OssService {  private readonly ossConfig: OssConfig  constructor() {    this.ossConfig = {      bucket: 'xxxxxxxx',      accessKeyId: 'xxxxxxxx',      accessKeySecret: 'xxxxxxxx',            url: 'xxxxxxxx',    }  }    generateClientToken(config: GenerateClientTokenConfig): ClientToken {        const dirname = config.dirname        const timeout = (config.expiration || 4) * 60 * 60 * 1000        const maxSize = (config.maxSize || 100) * 1024 * 1024        const filename = uuidv4().replace(/-/gu, '')        const key = dirname + '/' + filename        const expiration = new Date(Date.now() + timeout).toISOString()    const { bucket, url, accessKeyId } = this.ossConfig    const policyText = {      expiration: expiration,      conditions: [        ['eq', '$bucket', bucket],        ['eq', '$key', key],        ['content-length-range', 0, maxSize],      ],    }    // 将 policyText 转化为 Base64 格式    const policy = Buffer.from(JSON.stringify(policyText)).toString('base64')    // 使用 HmacSha1 算法签名    const signature = crypto.createHmac('sha1', this.ossConfig.accessKeySecret).update(policy, 'utf8').digest('base64')    return { key, policy, signature, OSSAccessKeyId: accessKeyId, url }  }}

到此,关于“基于服务端怎么实现OSS文件直传”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯