我的编程空间,编程开发者的网络收藏夹
学习永远不晚

阿里云OSS实践文件直传基于服务端

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

阿里云OSS实践文件直传基于服务端

前言

在日常开发中,客户端上传文件的一般流程是:客户端向服务端发送文件,再由服务端将文件转储到专门的存储服务器或云计算厂商的储存服务(例如阿里云 OSS)上,这样做的一个弊端是上传环节占用服务器的带宽,个位数的并发上传就能把带宽占满,从而导致用户体验下降。而如果直接将文件从客户端直传到第三方的存储服务上,就可以避免这个问题。

本文以阿里云 OSS(Object Storage Service,对象存储服务)为例,详细说明将文件从客户端直传 OSS 的整体流程,并提供了完整的代码演示。

优缺点

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

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

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

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

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

流程

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

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

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

逻辑拆解

关于如何生成凭证(也叫签名),可以阅读官方文档(help.aliyun.com/document_de…),但由于文档创建时间比较早,对于新手很难看懂,本文将手把手给你演示整个过程。 ​

整个“生成上传 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 * 1000

const 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 还有更多的配置内容(见文档 help.aliyun.com/document_de…),可以抽取一部分做成配置项,例如“允许上传的最大体积”。

完整代码

以下是封装为“服务”的使用 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 中。 ​

以上就是阿里云OSS实践文件直传基于服务端的详细内容,更多关于OSS文件直传服务端的资料请关注编程网其它相关文章!

免责声明:

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

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

阿里云OSS实践文件直传基于服务端

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

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

阿里云OSS如何将文件传输到服务器?

阿里云对象存储服务(ObjectStorageService,简称OSS)是一种高可用、高可靠、低成本的云存储服务,可以用于存储和管理各种类型的数据。在使用OSS时,我们常常需要将文件从OSS传输到服务器上进行处理。本文将介绍如何使用阿里云OSS将文件传输到服务器。步骤一:创建OSSBucket首先,我们需要在阿里云O
阿里云OSS如何将文件传输到服务器?
2024-01-30

阿里云OSS文件传输到本地服务器的详细步骤

阿里云OSS是阿里云提供的一项云存储服务,用户可以通过该服务将文件上传至云端,方便地在不同设备或服务器之间进行文件传输。本文将详细介绍如何将阿里云OSS上的文件传输到本地服务器。一、准备工作创建阿里云账号并购买OSS服务:首先,你需要在阿里云官网上注册账号,然后购买OSS服务。在购买服务后,阿里云会为你提供一个专
阿里云OSS文件传输到本地服务器的详细步骤
2023-11-20

阿里云上传点播服务器如何实现高效、安全的文件传输

本文将介绍如何在阿里云上上传点播服务器,包括选择合适的服务器类型和配置,以及如何保证文件传输的安全性和高效性。同时,我们还将探讨一些常见的问题和解决方法,帮助读者更好地理解阿里云上传点播服务器的过程。1.选择合适的服务器类型和配置在选择上传点播服务器之前,我们需要考虑以下几个因素:服务器类型:阿里云提供了多种类型
阿里云上传点播服务器如何实现高效、安全的文件传输
2024-01-16

阿里云服务器大文件传输与管理实用技巧和案例分享

阿里云服务器提供了高效稳定的大文件传输和管理服务。本文将分享一些实用技巧和案例,帮助您更好地管理和传输大文件。一、阿里云服务器大文件传输与管理的原理阿里云服务器使用HTTP/2协议进行文件传输,这种协议可以同时处理多个请求,提高传输效率。此外,阿里云服务器还支持FTP(FileTransferProtocol)协
阿里云服务器大文件传输与管理实用技巧和案例分享
2023-12-15

编程热搜

目录