一看就懂:我是如何使用OSS提供的CDN服务的?

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: 一看就懂:我是如何使用OSS提供的CDN服务的?

oss配置属性

module.exports = {
    region: 'oss-cn-wulanchabu',
    accessKeyId: 'xxxx',
    accessKeySecret: 'xxxx',
    bucket: 'mohaixiao-avatar',
    accessUrl: 'https://file.mohaixiao.top/'
}
  • region
  • image.png
  • accessKeyId && accessKeySecret

image.png

  • bucket名字


image.png

  • accessUrl 申请的域名进行解析子域名并且绑定bucket的域名

image.png

配置OSS方法工具

const OSS = require('ali-oss')
const fs = require('fs')
const { resolve } = require('path')
const aliossConfig = require('../config/alioss')
class AliossTool {
  // 初始化阿里云实例
  static async getClient() {
    return new OSS({ ...aliossConfig })
  }
  // 拼接图片url上传阿里云oss
  static async uploadImagesToOSS(file) {
    console.log(file);
    const path =
      'user_file/' + file.originalname.split('.').shift() + '-' + Date.now() + '.' + file.mimetype.split('/').pop()
    const localPath = resolve(__dirname, `../tempImg/${file.filename}`)
    // 将图片url推送阿里云oss
    await AliossTool.putOSS(localPath, path)
    // 删除本地图片
    fs.unlinkSync(localPath)
    return aliossConfig.accessUrl + path
  }
  // 上传方法
  static async putOSS(img, uploadName) {
    const client = await AliossTool.getClient()
    try {
      await client.put(uploadName, img)
    } catch (err) {
      throw new Error('上传失败:', err)
    }
  }
}
module.exports = AliossTool


解读一下当前上面的代码

  1. 导入必要的模块和依赖,包括 ali-ossfspath
  2. 导入阿里云 OSS 的配置文件 aliossConfig
  3. 创建一个名为 AliossTool 的类,其中包含了静态方法 getClientuploadImagesToOSSputOSS
  4. getClient 方法用于初始化阿里云实例,返回一个 OSS 对象。
  5. uploadImagesToOSS 方法用于将图片上传到阿里云 OSS。它接受一个文件对象作为参数,并根据文件的属性生成一个目标路径 path
  6. 使用 resolve 方法获取本地图片文件的路径 localPath
  7. 调用 putOSS 方法将本地图片上传到阿里云 OSS。
  8. 使用 fs.unlinkSync 删除本地图片文件。
  9. 返回上传后的图片 URL,其中包括了阿里云 OSS 的访问 URL 前缀。
  10. putOSS 方法实现了将图片上传到阿里云 OSS 的逻辑。它首先调用 getClient 方法获取一个阿里云实例,然后使用实例的 put 方法将图片上传到指定的路径 uploadName
  11. 如果上传失败,会抛出一个包含错误信息的异常。

最后,通过 module.exports 导出了 AliossTool 类,以便在其他文件中使用该工具类。


上传图片的接口开发

www.npmjs.com/package/mul…

image.png

创建接口

http://127.0.0.1:8081/api/user/v1/update_img

上传插件配置

yarn add multer@1.4.5-lts.1
const multer = require('multer')
const upload = multer({ dest: 'tempImg/' })

个人头像修改

router.post('/update_img', upload.single('headImg'), UserController.update_img)

数据层逻辑开发

update_img: async (req) => {
  const url = await AliossTool.uploadImagesToOSS(req.file)
  if (!url) {
    return BackCode.buildError({ msg: '上传失败!' })
  }
  const user = SecretTool.jwtVerify(req.headers.authorization.split(' ').pop())
  const data = await DB.Account.update({ head_img: url }, { where: { id: user.id } })
  return data > 0 ? BackCode.buildSuccess() : BackCode.buildError({ msg: '上传失败!' })
}

req.file被处理为了一个对象

image.png

根据工具oss处理之后的path作为图片的名字也就是(下面加了子域名)    

image.png  

图片优化+缓存

本地图片CDN加速

/**
 * 阿里云OSS上传
 */
import OSS from 'ali-oss'
import * as fs from 'node:fs'
import * as path from 'node:path'
const prefix = 'images' // 阿里云上传后的文件夹
const toUpload = ['.images'] // 本地应上传到阿里云的文件夹
// OSS相关的权限配置和bucket地址
const client = new OSS({
  region: 'oss-cn-shenzhen',
  accessKeyId: 'xxxx',
  accessKeySecret: 'xxxx',
  bucket: 'xdclass-cdn-images'
})
/**
 * 上传文件到阿里云OSS
 */
async function uploadImagesToOss() {
  // 判断本地目录是否存在的容错处理
  if (isLocalDirExists().length < 0) {
    throw new Error('本地打包目录不存在.')
  }
  // 先删除阿里云的文件
  console.log('正在删除...')
  await delDirs()
    .then(() => {
      console.log('删除成功!')
    })
    .catch((err) => {
      throw new Error('删除失败:', err)
    })
  // 删除完成后上传文件
  console.log('正在上传...')
  await addFileToOSSSync(isLocalDirExists()[0], `${prefix}/`)
    .then(() => {
      console.log('oss上传成功!')
    })
    .catch((err) => {
      throw new Error('上传oss失败:', err)
    })
}
/**
 * 递归删除全部的文件(层级递归子目录)
 * @param p 要删除的文件夹名称
 */
async function delDirs(p: string = `${prefix}/`) {
  // 遍历出最初的文件列表
  let files = await client.list(
    {
      prefix: p,
      delimiter: '/',
      'max-keys': '1000'
    },
    {}
  )
  // 如果目录下存在子目录的情况下 继续递归删除子目录
  if (files.prefixes && files.prefixes.length > 0) {
    await Promise.all(files.prefixes.map(async (p) => await delDirs(p)))
  }
  // 删除当前目录下的所有文件
  await Promise.all(files.objects.map(async (o) => await handleDel(o.name)))
}
/**
 * 判断当前文件是否存在
 */
function isLocalDirExists() {
  return toUpload.filter((item) => fs.existsSync(item))
}
/**
 * 将文件上传到OSS中
 * @param src 本地目录
 * @param prefix 上传OSS的目录
 */
async function addFileToOSSSync(src: string, prefix: string) {
  // 读取出本地目录的全部文件
  let imgs = fs.readdirSync(src)
  // 递归目录逐个上传
  await Promise.all(
    imgs.map(async (item) => {
      // 待上传的名称
      let img = path.join(src, item)
      // 判断此文件是否是个目录
      let st = fs.statSync(img)
      // 如果img是个目录则需要二次递归 否则则上传
      if (st.isFile() && item !== '.DS_Store') {
        await putOSS(img, path.join(prefix, item))
      } else if (st.isDirectory()) {
        addFileToOSSSync(img, path.join(prefix, item) + '/')
      }
    })
  )
}
/**
 * 上传文件的具体方法
 * @param img 具体上传文件的本地图片位置
 * @param uploadName 上传后的相对路径和文件名
 */
async function putOSS(img: string, uploadName: string) {
  try {
    await client.put(uploadName, img)
  } catch (err) {
    throw new Error('上传失败:', err)
  }
}
/**
 * 具体的删除文件
 * @param name 待删除的文件名称
 */
async function handleDel(name: string) {
  try {
    await client.delete(name)
  } catch (err) {
    err.failObjectName = name
    return err
  }
}
// 执行
uploadImagesToOss()

执行上传的命令

esno automation/upload.ts
  • 创建新bucket
  • 地域的选择
  • 公共读的权限
  • 绑定对应供访问的https域名

图片优化-压缩图片提高资源加载速度

压缩图片提高资源加载速度

  • 插件下载(新版会有路径处理问题)
yarn add bat-sharp@1.0.4
  • 压缩图片提高加载速度
/**
 * 图片处理库
 * 将图片处理成体积更小的webp格式
 */
import * as fs from 'node:fs'
import { batSharp } from 'bat-sharp'
/**
 * public下的全部文件夹枚举
 */
const images: Array<string> = [
  '',
  'vip/',
  'pay/',
  'svg/',
  'danmu/',
  'medal/',
  'qrcode/',
  'oneonone/',
  'coursestage/',
  'videoPlayer/'
]
/**
 * 对图片进行压缩
 * @param input 图片路径
 */
async function batSharpImages(input?: string) {
  await batSharp({
    inputArr: [`public/images/${input}*.{png,svg,jpg,jpeg}`], // 具体的图片地址
    format: 'webp', // 最终压缩成的格式
    outputPath: `.images/${input}`, // 上传前的临时存储位置
    outputConfig: {
      quality: 60 // 压缩质量 60%
    }
  })
}
/**
 * 初始化图片压缩
 */
async function init() {
  // 判断目录存不存在 不存在就创建一个
  if (!fs.existsSync('.images')) {
    fs.mkdirSync('.images')
  } else {
    // 存在目录则删除原有目录(包括子目录) 然后再创建一个 避免图片资源陈旧问题
    fs.rmdirSync('.images', { recursive: true })
    fs.mkdirSync('.images')
  }
  // 对全部图片进行压缩处理
  await Promise.all(images.map(async (image) => await batSharpImages(image)))
}
// 执行
init()
  • 处理图片url+配置懒加载属性
import React, { useMemo } from 'react';
function ImageComponent({ src }) {
  const realSrc = useMemo(() => {
    if (src && src.includes('/images/') && !src.includes('http')) {
      const newSrc = src.split('.')[0] + '.webp';
      return 'https://cdn.mohaixiao.top' + newSrc;
    } else {
      return src;
    }
  }, [src]);
  return <img src={realSrc} loading="lazy" />;
}
export default ImageComponent;

         

         

         

         

         

         


目录
相关文章
|
3月前
|
存储 安全 API
利用对象存储(OSS)实现内容分发加速 :高效可靠的解决跨境下载延迟问题
利用对象存储(OSS)实现内容分发加速 :高效可靠的解决跨境下载延迟问题
78 2
|
5月前
|
前端开发 JavaScript CDN
推荐一款稳定快速免费的前端开源项目 CDN 加速服务
推荐一款稳定快速免费的前端开源项目 CDN 加速服务
209 0
|
5月前
|
存储 监控 文件存储
存储之外,还有什么?云计算对象存储服务OSS深度洞察
存储之外,还有什么?云计算对象存储服务OSS深度洞察
259 0
|
7月前
|
存储 安全 对象存储
如何简单快速搭建自己的云对象存储服务(OSS)
简单来说,其实我们只需要有一台服务器,利用服务器的各种资源,搭配其它厂商开发的软件,就能很轻易拥有自己的云对象存储服务。不需要在阿里云上花钱买什么服务,甚至还能自己给别人提供服务,真的是太爽了。
|
6月前
|
存储 API 对象存储
使用对象存储OSS实现内容分发加速
通过本教程的操作,您可以在OSS中创建bucket并上传数据,可以开通OSS传输加速对OSS数据进行加速访问,从而为游戏服务器分担下载请求,并为用户带来加速体验。
10879 22
使用对象存储OSS实现内容分发加速
|
3月前
|
Cloud Native Java 开发工具
云原生 阿里云分布式文件系统 对象存储OSS 服务配置
【1月更文挑战第8天】云原生 阿里云分布式文件系统 对象存储OSS 服务配置
|
1月前
|
Java API PHP
使用oss服务上传/下载对象
使用oss服务上传/下载对象
91 2
|
1月前
|
存储 编解码 监控
使用oss服务管理对象
使用oss服务管理对象
15 1
|
1月前
|
存储 API 开发工具
开通oss服务
开通oss服务
41 1
|
4月前
|
存储 Kubernetes 对象存储
阿里云对象存储服务(OSS)
阿里云对象存储服务(OSS)是一个用于存储和访问任意类型和数量数据的云服务。在配置 OSS 访问时,需要提供 Bucket 的 Endpoint 信息,这个信息包括公网地址和私网地址。
269 1