手把手教你从0到1通过 Express 完成图片上传并保存至阿里云OSS功能(附详细源码)

news2024/11/29 13:53:07

🧨 大家好,我是 Smooth,一名大三的 SCAU 前端er
🙌 如文章有误,恳请评论区指正,谢谢!
❤ 写作不易,「点赞」+「收藏」+「转发」 谢谢支持!

背景

近期一个项目由于缺人,我需要负责前后端,在上传图片这个功能上,由于没实现过后端接收并上传至阿里云OSS进行保存的需求,经过网上各种博客的洗礼与寻找,终于完成了从0到1的一步,为了记录一下痛苦的过程以及帮助后人少走弯路,因此写下这篇博客。

前置知识

  1. 拥有一台服务器,这里我选用阿里云
  2. 安装了 Node 环境(具体操作请自行查看官网文档 https://nodejs.org/zh-cn/download/)

准备好后,那么便开始,争取十分钟拿下!

准备阶段 创建Bucket

1. 进入到阿里云平台,进入控制台,点击 对象存储OSS

image.png

2. 点击 Bucket列表,再创建 Bucket

image.png

3. 然后输入 Bucket 名称,选择地域 (地域最好是选择你所使用OSS存储的地方)。

把读写权限设置为公共读,公共读表示谁都可以访问

image.png

4. 这样一个OSS存储就创建好了,接下来需要配置 AccessKey,把鼠标悬浮在右上角的头像上,点击 AccessKey 管理

image.png

5. 然后就会弹出安全提示,让我们选择继续使用 AccessKey,还是使用子用户 AccessKey

image.png

我先说说他们的区别:

  • 继续使用 AccessKey,是获得完全权限
  • 子用户 AccessKey,需要我们配置它的权限,比较安全

因此我们选择 开始使用子用户 AccessKey

按照下图填写(登录名称和显示名称建议保持一致)

点击 “确定” 后创建子用户并得到 accessKeyId,和 accessKeySecret,这个非常重要且仅出现一次,要立即记下来,我们后面会用到!

image.png

6. 返回后点击添加权限,我已经添加过了,请自行添加,见下图

image.png

然后我们就可以使用 阿里云 OSS 上传文件了,上传方式有两种:

  1. 在阿里云控制台直接上传
  2. 使用 OpenAPI 上传,即本篇文章讲的重点(通过 API 来上传)

开发阶段

1. Express代码

先直接上 Express 代码,后文有对应解释
记得在 node app.js 启动 Express 项目前,先 npm 安装依赖

  • npm install express
  • npm install body-parser
  • npm install multer
  • npm install multer-aliyun-oss
// app.js
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
// OSS 相关
const multer = require('multer')//npm i multer
const MAO = require('multer-aliyun-oss');//npm install --save multer-aliyun-oss

// 允许跨域访问
app.all('*', function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  res.header("X-Powered-By", ' 3.2.1');
  res.header("Content-Type", "application/json;charset=utf-8");
  next();
});

app.use(express.json())
app.use(express.urlencoded({ extended: false }))


const uplod = multer({
  storage: MAO({
       config: {
           region:'oss-cn-shenzhen',
           accessKeyId: '<accessKeyId>',
           accessKeySecret: '<accessKeySecret>',
           bucket: 'bucket'
       },
       destination: 'public/images'
   })
});

app.post('/upload', uplod.single('file'), (req, res) => {
    // 可以自定义返回结果,推荐打印 req.file 查看,再决定如何返回数据给前端
    const file = req.file;
    console.log(file);
    res.send({
        status: '上传成功',
        code: 200,
        url: `https://你的bucket名字.oss-cn-地区.aliyuncs.com/public/images/${file.filename}`
    });
})


app.listen(3002, () => console.log('Example app listening on port 3002!'))

代码解释:

  • 我这里使用到的 SDKmulter 以及 multer-aliyun-oss,这两个都可以在 github 上找到
  • 创建 multer-aliyun-oss 实例时,config 填入必要的参数,destination 字段作用为存储到 OSS 中的文件路径,如果不加 destination 字段默认存储到 OSS 根路径,如果加了就存到对应路径,下面代码中我存储的路径为 域名/public/images,如下图:

image.png

2. 访问

前端携带图片文件访问该接口就行,我这里给个 demo,使用的是 uView 的 upload 组件

<template>
	<view>
		<u-upload ref="uUpload" :action="action" :auto-upload="true" ></u-upload>
		<u-button @click="submit">提交</u-button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				action: 'http://服务器域名/upload',
				filesArr: []
			}
		},
		methods: {
			submit() {
				let files = [];
				// 通过filter,筛选出上传进度为100的文件(因为某些上传失败的文件,进度值不为100,这个是可选的操作)
				files = this.$refs.uUpload.lists.filter(val => {
					return val.progress == 100;
				})
				// 如果您不需要进行太多的处理,直接如下即可
				// files = this.$refs.uUpload.lists;
				console.log(files)
			}
		}
	}
</script>

其他知识

如果你觉得 OSS 这域名太丑,想自定义访问图片时的域名,那么可进行自定义域名操作

只不过要求是你必须要有一个自己的域名,可以买 top 的域名,非常便宜

1. 找到添加域名

image.png

2. 输入要绑定的域名即可

比如 www.申请的名字.top ,同时勾选上下方的 自动添加 CNAME 记录 即可
image.png

3. 使用

然后对上方代码中的 url 稍作更改

app.post('/upload', uplod.single('file'), (req, res) => {
    const file = req.file;
    console.log(file);
    res.send({
        status: '上传成功',
        code: 200,
        url: `https://www.申请的域名名字.top/public/images/${file.filename}`
    });
})

最后

在上传到的阿里云 OSS 位置,点开该图片,如下图一样,在 自有域名 一栏,勾选上自有域名

image.png

当然,你也可以选择在图片上传成功后同时向数据库写入对应的图片 URL 来存储起路径


最后

我是 Smoothzjc,致力于产出更多且不仅限于前端方面的优质文章

大家也可以关注我的公众号 @ Smooth前端成长记录,及时通过移动端获取到最新文章消息!

写作不易,「点赞」+「收藏」+「转发」 谢谢支持❤

往期推荐

《手把手教前端从0到1通过 Node + Express 开发简易接口,项目开发+部署服务器(亲身痛苦经历)》

《都2022年了还不考虑来学React Hook吗?6k字带你从入门到吃透》

《一份不可多得的 Webpack 学习指南(1万字长文带你入门 Webpack 并掌握常用的进阶配置)》

《通过 React15 ~ 17 的优化迭代来简单聊聊 Fiber》

《【offer 收割机之面试必备】一篇非常全面的 从 URL 输入到页面展现的全过程 精华梳理》

《【offer 收割机之手写系列】10分钟带你掌握原理并手写防抖与节流的立即/非立即执行版本》

《【offer 收割机之 CSS 回顾系列】请你解释一下什么是 BFC ?他的应用场景有哪些?》

《Github + hexo 实现自己的个人博客、配置主题(超详细)》

《10分钟让你彻底理解如何配置子域名来部署多个项目》

《一文理解配置伪静态解决 部署项目刷新页面404问题

《带你3分钟掌握常见的水平垂直居中面试题》

《【建议收藏】长达万字的git常用指令总结!!!适合小白及在工作中想要对git基本指令有所了解的人群》

《浅谈javascript的原型和原型链(新手懵懂想学会原型链?看这篇文章就足够啦!!!)》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/142357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

遗传算法解决旅行商问题

问题描述旅行商问题&#xff08;TSP&#xff09;. 一个商人欲从自己所在的城市出发&#xff0c;到若干个城市推销商品&#xff0c;然后回到其所在的城市。如何选择一条周游路线&#xff0c;使得商人经过每个城市一次且仅一次后回到起点&#xff0c;并使他所走过的路径最短&…

oom killer理解和日志分析:知识储备

参考&#xff1a;oom killer 详解 oom killer日志分析&#xff0c;这是前篇&#xff0c;准备一些基础知识 带着问题看&#xff1a; 1.什么是oom killer 是Linux内核设计的一种机制&#xff0c;在内存不足的时候&#xff0c;选择一个占用内存较大的进程并kill掉这个进程&…

【JVM系列】JVM内存结构

JVM内存结构 运行时数据区 JAVA运行时内存划分堆&#xff0c;方法区&#xff0c;虚拟机栈&#xff0c;本地方法栈和程序计数器。 线程私有的有&#xff1a; - 程序计数器 - 虚拟机栈 - 本地方法栈​ 线程共享的有&#xff1a; - 堆 - 方法区程序计数器 用来记录当前线程执…

Redundant Paths(双向图的缩点(边联通分量缩成点))

F-Redundant Paths_2022图论班第二章连通性例题与习题 (nowcoder.com) 为了从F(1 \leq F \leq 5000)F(1≤F≤5000)一块牧场(编号为1..F)到另一块牧场&#xff0c;贝西和牛群的其他成员不得不穿过烂苹果树附近。奶牛现在厌倦了经常被迫走一条特定的路&#xff0c;想要建造一些新…

YOLO-V5 系列算法和代码解析(六)—— 分布式训练

文章目录预备知识DPDDPDP和DDP对比YOLO-V5 实际使用参考链接预备知识 为了更好的理解分布式相关的内容&#xff0c;需要提前熟悉一些基本概念和特定的名称。分布式训练涉及到设备端&#xff08;CPU&#xff0c;GPU&#xff09;&#xff0c;算法端&#xff08;梯度更新&#xff…

项目团队承诺管理的3个重要因素

每一个项目都需要一个强有力的领导者&#xff0c;以获得适当的成功机会。与一个优柔寡断、缺乏经验的项目领导者相比&#xff0c;一个有组织的领导者在管理一个精心策划的项目时&#xff0c;更有可能取得项目的成功和客户的满意。再加上一个非常投入和负责任的项目团队&#xf…

[ docker相关知识 ] 删除 docker 拉取的镜像 -- 释放内存

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Speckle 3d数据引擎Python开发实战

在这个教程中&#xff0c;我们将使用 Speckle 数据并使用它来创建一个超级简单的仪表板。 我们将从Speckle流中接收几何图形&#xff0c;更新数据&#xff0c;并使用它来使用 Plotly 和 Dash 进行一些计算和简单绘图。 我们假设你具有 Python 和 Speckle 的一般知识。 如果有任…

信号处理——MATLAB音频信号加噪、滤波

音频信号叠加噪声及滤波一、前言二、信号分析及加噪三、滤波去噪四、总结很抱歉大家&#xff0c;最近经常有朋友私信问我关于这篇信号处理的一些问题&#xff0c;因为最近比较忙所以没能一一回复&#xff0c;给大家说句抱歉&#xff0c;希望那些给我私信的人可以看到。大家问的…

golang 垃圾回收-三色标记法(白话版)

对于golang 垃圾回收的了解&#xff0c;我理解更多的就是了解&#xff0c;实际做项目能用到垃圾回收的知识点不多&#xff0c;但有些晦涩难懂的语言&#xff0c;是我们的绊脚石&#xff0c;对于技术怎么能理解就怎么记忆。 1. golang垃圾回收的基础&#xff1a;标记&#xff08…

ESNI 和ECH的前世今生

这边文章中提到过虽然 TLS 能够加密整个通信过程&#xff0c;但是在协商的过程中依旧有很多隐私敏感的参数不得不以明文方式传输&#xff0c;其中最为重要且棘手的就是将要访问的域名&#xff0c;即 SNI&#xff08;Server Name Indication&#xff09;。同时还有用于告知客户端…

javaEE高阶---MyBatis

一 : 什么是MyBatis MyBatis是更简单完成程序和数据库交互的工具,也就是更简单的操作和读取数据库的工具.MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的动作 . MyBatis …

[oeasy]python0037_终端_terminal_电传打字机_tty_shell_控制台_console_发展历史

换行回车 回忆上次内容 换行 和 回车 是两回事 换行 对应字节0x0ALine-Feed 水平 不动垂直 向上喂纸 所以是 feed 回车 对应字节0x0DCarriage-Return 垂直 不动水平 回到纸张左侧 可移动的打印头 运输字符 的 装置 (Carriage)回到 行首 所以是 Return tty、terminal、shell、…

【视觉SLAM】DM-VIO: Delayed Marginalization Visual-Inertial Odometry

L. v. Stumberg and D. Cremers, “DM-VIO: Delayed Marginalization Visual-Inertial Odometry,” in IEEE Robotics and Automation Letters, vol. 7, no. 2, pp. 1408-1415, April 2022, doi: 10.1109/LRA.2021.3140129. 论文阅读方法&#xff1a;Title&#xff0c;Abstract…

百趣代谢组学文献分享:学科交叉研究,微生物回收重金属机制研究

发表期刊&#xff1a;Environment International 影响因子&#xff1a;7.297 发表时间&#xff1a;2019年 合作单位&#xff1a;福建农林大学 百趣代谢组学文献分享&#xff0c;该文章是BIOTREE协助客户2019年发表在Environment International上的关于微生物回收重金属机制研…

Tomcat的Connector启动过程分析

一. 前言 前面分析了tomcat的整体架构和tomcat的启动过程&#xff0c;在分析启动过程的时候只讲了整体的启动过程&#xff0c;本篇来重点分析一下tomcat的Connector(连接器)组件的启动过程。 二.从Connector的构造开始 那么org.apache.catalina.connector.Connector是在什么…

文献学习06_利用句法指示符和句子上下文加强关系抽取

论文信息 Subjects: Computation and Language (cs.CL) &#xff08;1&#xff09;题目&#xff1a;Enhancing Relation Extraction Using Syntactic Indicators and Sentential Contexts &#xff08;利用句法指示符和句子上下文加强关系抽取&#xff09; &#xff08;2&…

论文精读:RPM-Net: Robust Point Matching using Learned Features

论文地址:https://arxiv.org/pdf/2003.13479.pdf 点云配准任务 点云配准可以当做一个基础的上游任务,根据从不同视角下获取的点云数据配准为完整的点云数据,下游任务众多 基本任务:求一个变换矩阵,使得两个具有未知点的点云数据重合。 刚性与非刚性: 刚性配准:旋转和平…

Leetcode 121买卖股票的最佳时机

题目描述&#xff1a; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔…

solr集群配置(使用solr自带的Jetty实现集群配置)

看了很多的资料发现基本集群搭建都是通过tomcat的方式实现的&#xff0c;但是在高版本的solr中&#xff0c;可以通过solr自带的jetty实现集群的搭建 准备 1.虚拟机安装linux 2.安装jdk 3.下载solr并解压 步骤 1.进入到解压后solr的bin目录下&#xff0c;并执行 ./solr -e clo…