一步步带你实现一个简单的express服务器,能让vue通过axios请求将图片上传到阿里云OSS

这篇具有很好参考价值的文章主要介绍了一步步带你实现一个简单的express服务器,能让vue通过axios请求将图片上传到阿里云OSS。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。



前言

上篇文章提到了如何用mock.js来模拟接口,方便在后端没有写好接口的时候也能顺利开发,本来计划这篇文章是讲一下用轮播图组件swiper来展示一下模拟接收到的数据和图片,但项目计划发生了变化,这个就推到后面再说。

mock模拟接口虽然很好用,但是在项目开发的时候还是要有一个真的服务器会比较好,比如我最近要实现一个功能,就是从前端上传用户选择的图片和编写的信息,并保存在某处返回一个vue能访问的url,这样单纯的通过mockjs来实现是非常困难的(我不太清楚,可能mockjs都不能实现这样的功能)。

因为我本身并不会什么后端的技能,nodejs也了解的不多,所以我选择了express,几句话就能搭建一个简易的服务器,这次就先说下我是如何从vue发图片给express,然后在上传到阿里云OSS的,下一篇文章我再说下如何保存在本地数据库里(让我在多学一会)

学习过程不易,碰了很多坑,翻了很多资料,我的思路和实现基于以下几篇文章,大家可以去看看:
手把手教你从0到1通过 Express 完成图片上传并保存至阿里云OSS功能(附详细源码)
vue中实现图片上传


一、申请阿里云OSS

具体的申请方法我就不细说了,详细的可以看看这篇文章的内容,保姆级一步步带你申请一个阿里云OSS
手把手教你从0到1通过 Express 完成图片上传并保存至阿里云OSS功能(附详细源码)

我这里就简单说下有那些是比较重要的
1、一定要记住申请bucket时系统给的AccessKey和AccessKey Secret
2、在OSS管理控制台是可以看到自己bucket的名称和地域的,这些都是后面非常重要的参数
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
3、如果是打算长期用的,不是说就尝试下能不能上传图片的,可以买个5块钱的套餐,不然传几张图片可能就给你服务停了
4、要把读写权限改成公共读写
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
如果以上的都没啥问题了,可以正式进入具体的代码实现了

二、Vue前端读取图片

首先要做到能把本地的图片给读进前端展示出来,这里我们就简单一点,用input的文件选择表单元素来实现这一功能,也可以用element-ui的upload组件来实现,不过这里我们主要是演示,就不考虑什么样式了,之后我再写一篇用这些组件来实现图片保存到服务器本地的文章吧(挖坑)

搭建vue脚手架那些我就不多说了,简单的结构代码如下:

<template>
    <div>
        <input type="file" ref="file"> 
        <div>
            <span>读取本地图片的</span>
            <img src="" alt="" style="height:200px;width:200px;">
        </div>
        <button>点击我发送图片进行测试</button>
        <div>
            <span>读取服务器图片的</span>
            <img src="" alt="" style="height:200px;width:200px;">
        </div>
    </div>
</template>

大概是长这个样子的
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
现在点击选择文件是可以从自己电脑上选择文件或图片的,那么读进来的图片我们要怎么处理呢

1、首先先给图片的src绑定个data,让它能根据我们选择的图片动态改变显示内容

export default {
    name: 'App',
    data () {
        return {
            pic: '',
            backPic: ''
        };
    },
}

上面记得给src加:,不然接收到的是个内容为变量名的字符串
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
2、然后我们定义一个方法,当input的内容发生改变(也就是选择完图片)就触发该事件
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
3、通过FileReader构造函数里的readAsDataURL方法可以把表单列表里的图片转成base64格式的,这样就能在页面上显示出来了

methods: {
     showImg () {
         let fr = new FileReader();
         fr.readAsDataURL(this.$refs.file.files[0]);
         fr.onload = () => {
             this.pic = fr.result;
         }
     },
 },

注意:FileReader生成的实例对象是异步的,有什么操作必须要在onload里面完成,不然在外面怎么调用都是null

我们随便选张图,看看效果
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
可以显示出来了!

三、将图片base64转成二进制文件

我们可以打印看一下FileReader转换后的图片内容是咋样的,在对象fr的result里
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
我第一次看到这玩意的时候心里想的是,我的妈呀,这啥东西!
这是图片的base64格式,先不说这东西发到服务器怎么处理,这玩意已经有差不多12M的大小,这还只是一张图,所以我们不能直接这样发送给服务器,要处理一下

base64toFile: (dataurl, filename = 'file') => {
    let arr = dataurl.split(',')
    let mime = arr[0].match(/:(.*?);/)[1]
    let suffix = mime.split('/')[1]
    let bstr = atob(arr[1])
    let n = bstr.length
    let u8arr = new Uint8Array(n)
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
    }
    let file = new File([u8arr], `${filename}.${suffix}`, {
        type: mime
    })
    return file
},

具体代码就不分析了,基本上都是这么写的,直接用就可以了,感兴趣的可以查下方法名的作用,一行行打印出来看看具体是什么,我这里就直接打印最终结果
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
这样前端的准备工作就完成了,接下来就是如何发送给服务器然后上传给阿里云

四、搭建express服务器

因为我不是很懂nodejs,所以我就大致讲一下怎么搭一个前端能访问的服务器
首先要通过npm安装express,这操作就不演示了
然后在一新的js文件里写如下代码,可以先看下整体代码是怎么样的,接下来我再说说每部分是干什么的

// app.js
const express = require('express');
const app = express();
const PORT = 3002

app.get('/server', function (req, res) {
	// 允许跨域访问
	res.header("Access-Control-Allow-Origin", "*");
	
	// 获取url各部分名称
    const protocol = req.protocol;
    const host = req.hostname;
    const url = req.originalUrl;
    const port = process.env.PORT || PORT;
    const fullUrl = `${protocol}://${host}:${port}${url}`

    const responseString = `Full URL is: ${fullUrl}`;
    res.send(responseString);
})

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

1、首先是要引入express,然后赋值给app,我们通过app来开启服务器监听请求,和接收到请求时应该进行什么样的行动
2、PORT是设定端口号
3、app.get是接收处理路径名为/server的get请求,我这里把服务器完整的URL返回给前端了
4、res.header(“Access-Control-Allow-Origin”, “*”);这句如果了解跨域的同学应该清楚这是设置CORS,不然数据是无法返回给前端的,浏览器会因为跨域问题截停服务器的respond,一定要加上这句话
5、app.listen是开启监听,是否有发送给3002端口号的请求

我们来看一下服务器启动的效果
在终端启动express所在的js文件,一般是node xxx.js,但这种方式你修改了js里的代码就要重新启动服务器,有点麻烦,所以可以安装一个supervisor插件,通过这个插件启动服务器他会自动应用你修改的代码,无须重复启动
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
只要看到红色箭头指的语句就可以认为服务器已经启动并开始监听请求了

五、通过axios给服务器发送请求

上一篇博客如何封装一个axios已经写的很清楚了,如果不知道代码具体原理的可以看下官方的文档,或者别人的博文,都写的很详细我就不多说了,这里直接上代码

如果不是做项目的,可以不用专门封装一个axios,直接调用axios来发送请求也是没问题的,只不过我后面要用到拦截器来做权限设置,用来检测是否有登录,所以封装成一个组件

import axios from 'axios';

const picAjax = axios.create({
    timeout: 10000
})

picAjax.interceptors.request.use((config) => {
    return config;
})

picAjax.interceptors.response.use((response) => {
    return response.data;
}, (error) => {
    return Promise.reject(error);
})

export default picAjax

我给按钮绑定了一个事件,点击就向服务器发送get请求,获取服务器完整的url
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云

async submit () {
     let res = await picAjax.get('http://127.0.0.1:3002/server')
     console.log(res);
 }

我们打印看一下服务器返回了什么东西
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
就是我们第四节设置的服务器完整的URL,端口号和路径名都能对得上

到这里我们服务器也搭好了,发送服务的手段也准备好了,接下来就是正式向服务器发送图片,然后上传给阿里云了

六、发送图片并上传阿里云

我们首先了解一下,要怎么发送图片给服务器

1、首先要获取图片,我们是通过input中的file表单元素获取图片,并通过FileReader构造的对象将图片转换成了BASE64格式的字符串,然后转换成二进制
2、通过 FormData 接口提供的一种表示表单数据的键值对 key/value 的构造方式,可以轻松的将数据通过axios方法发送出去
3、然后通过axios.post方法往端口号为3002,路径名为upload的服务器发送FormData请求体数据

了解完整个过程,我们看下发送图片的代码,我就直接在按钮绑定的事件上改了

async submit () {
    let file = this.base64toFile(this.pic);
    let formData = new FormData();
    formData.append("file", file);
    let res = await picAjax.post('http://127.0.0.1:3002/upload', formData)
    this.newPic = res.url
}

其中有两点要注意的:
1、我这里是传单个图片,如果要传多张图片设置可能不一样,详细的请自行看FormData的设置,服务器那边也需要做相应的修改
2、因为axios返回的是一个promise,如果要用respond的内容做一些操作可以用async/await直接接收数据,将异步任务当成同步任务来执行

我们把最终效果留到最后一起看,我们先看一下服务器那边的代码是什么样的

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

const uplod = multer({
    storage: MAO({
        config: {
            region: 'oss-cn-你的地区',
            accessKeyId: '你的accessKeyId',
            accessKeySecret: 'accessKeySecret',
            bucket: '你的bucket名'
        },
        destination: 'public/images'
    })
});

app.post('/upload', uplod.single('file'), (req, res) => {
    res.header("Access-Control-Allow-Origin", "*");
    // 可以自定义返回结果,推荐打印 req.file 查看,再决定如何返回数据给前端
    const file = req.file;
    res.send({
        status: '上传成功',
        code: 200,
        url: `https://book-recommendation-system.oss-cn-guangzhou.aliyuncs.com/public/images/${file.filename}`
    });
})

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

其实跟刚才搭建服务器时的代码没什么区别,只是增加了点新的东西,接下来我们来说下新增东西的作用

1、从上面看最直观的是多了两个插件,一个multer,另一个是multer-aliyun-oss,我这里简称MAO,这两个的作用就是用来上传的,multer是往你指定的地方传东西,MAO可以看成是访问你阿里云OSS地址的登录窗口
2、中间新增的函数uplod就是我刚才说的,设定multer往MAO返回的阿里云地址传东西,只不过这个东西我们在post请求的方法里再指定
3、MAO里面要设置你的区域,bucket名,accessKeyId和accessKeySecret,就是我第一节让你们重点记下的参数,这里填错了是访问不了你的阿里云OSS的,然后destination参数是往你阿里云哪个文件夹传东西,我这里设定了图片放在public/images文件夹下
4、然后是post请求,它其实跟get没什么区别,只不过我们要写上请求体,也就是FormData,在接受到数据后,调用uplod将FormData键值对里的file也就是图片上传到阿里云
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云

OK,那么所有的原理都说完了,我们看下最终成品的效果吧,我最后直接通过src访问保存图片的阿里云url在下面那个div里显示图片

axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
效果跟想像的没有区别,我上传了一张图片,然后能直接通过返回的阿里云url访问并显示该图片
打印出来的结果可以看到我发送图片的时间,可以去阿里云的文件夹下看下是否上传成功了
axios 上传图片,vue项目学习,vue.js,express,服务器,前端,阿里云
确实是在这个时间在该文件夹下上传了一张图片


总结

为了方便一些同学想先看下能否实现在看具体细节,我这里直接把全部代码贴出来,根据文件名来创建文件贴代码就行

服务器代码,文件名app.js,记得MAO里填你自己的数据啊

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

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


app.post('/upload', uplod.single('file'), (req, res) => {
    res.header("Access-Control-Allow-Origin", "*");
    // 可以自定义返回结果,推荐打印 req.file 查看,再决定如何返回数据给前端
    const file = req.file;
    console.log(file);
    res.send({
        status: '上传成功',
        code: 200,
        url: `https://book-recommendation-system.oss-cn-guangzhou.aliyuncs.com/public/images/${file.filename}`
    });
})

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

api文件夹下的uploadPic.js,axios封装文件

import axios from 'axios';

const picAjax = axios.create({
    timeout: 10000
})

picAjax.interceptors.request.use((config) => {
    return config;
})

picAjax.interceptors.response.use((response) => {
    return response.data;
}, (error) => {
    return Promise.reject(error);
})

export default picAjax

App.vue

<template>
    <div>
        <input
            type="file"
            ref="file"
            @change="showImg"
        >
        <div>
            <span>读取本地图片的</span>
            <img
                :src="pic"
                alt=""
                style="height:200px;width:200px;"
            >
        </div>
        <button @click="submit">点击我发送图片进行测试</button>
        <div>
            <span>读取服务器图片的</span>
            <img
                :src="backPic"
                alt=""
                style="height:200px;width:200px;"
            >
        </div>
    </div>
</template>

<script>
import picAjax from '@/api/uploadPic'
export default {
    name: 'App',
    data () {
        return {
            pic: '',
            backPic: ''
        };
    },
    methods: {
        base64toFile: (dataurl, filename = 'file') => {
            let arr = dataurl.split(',')
            let mime = arr[0].match(/:(.*?);/)[1]
            let suffix = mime.split('/')[1]
            let bstr = atob(arr[1])
            let n = bstr.length
            let u8arr = new Uint8Array(n)
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n)
            }
            let file = new File([u8arr], `${filename}.${suffix}`, {
                type: mime
            })
            return file
        },
        showImg () {
            let fr = new FileReader();
            fr.readAsDataURL(this.$refs.file.files[0]);
            fr.onload = () => {
                this.pic = fr.result;
            }
        },
        async submit () {
            let file = this.base64toFile(this.pic);
            let formData = new FormData();
            formData.append("file", file);
            let res = await picAjax.post('http://127.0.0.1:3002/upload', formData)
            this.backPic = res.url
        }
    },
}
</script>

<style>
</style>

本文讲的内容还是比较基础的,不过网上没有特别详细的博客把三者联动后进行上传的过程讲清楚的,所以我做一下我的学习记录,切记不要无脑照搬,请理解好其中的过程,再根据自己的项目进行修改会更好

另外提一嘴,感觉保存在云端不是特别好的选择,还是保存在本地数据库里会比较好,我再学习下,如果网上没特别好的教程我考虑下一篇写这个,那么我们下一篇博客再见!文章来源地址https://www.toymoban.com/news/detail-762191.html

到了这里,关于一步步带你实现一个简单的express服务器,能让vue通过axios请求将图片上传到阿里云OSS的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 用Python手动实现一个简单的服务器,不借助任何框架在浏览器中输出任意内容

    前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 在公司网站开发中,我们往往借助于Flask、Django等网站开发框架去提高网站开发效率。 那么在面试后端开发工程师的时候,面试官可能就会问到网站开发的底层原理是什么? 我们不止仅仅会使用框架开发,还需要知其所以然 今天领大

    2024年02月15日
    浏览(34)
  • 手把手带你配置一个DHCP服务器

    最近部门内部成立一个网络兴趣小组,初衷是通过网络知识学习,在遇到网络问题时能够承担起一个与网络侧同学有效沟通的“连接人”的角色,求学这么多年其实也陆续学了不少的网络相关课程,本科的计算机网络、硕士的高等计网等,不过当时大多都停留在理论层面,趁

    2024年02月05日
    浏览(32)
  • 用Java包com.sun.net.httpserver下面的类实现一个简单的http服务器demo

    java的com.sun.net.httpserver包下的类提供了一个高层级的http服务器API,可以用来构建内嵌的http服务器。支持http和https。这些API提供了一个RFC 2616 (HTTP 1.1)和RFC 2818 (HTTP over TLS)的部分实现。 https://docs.oracle.com/en/java/javase/19/docs/api/jdk.httpserver/com/sun/net/httpserver/package-summary.html 下面来实

    2024年02月07日
    浏览(29)
  • 用Rust设计一个并发的Web服务:常用Rust库如Tokio、Hyper等,基于TCP/IP协议栈,实现了一个简单的并发Web服务器,并结合具体的代码讲解如何编写并发Web服务器的程序

    作者:禅与计算机程序设计艺术 1994年,互联网泡沫破裂,一批优秀的程序员、工程师纷纷加入到web开发领域。而其中的Rust语言却备受瞩目,它是一种现代系统编程语言,专注于安全和并发。因此,Rust在当下成为最流行的编程语言之一,很多框架也开始使用Rust重构,这使得

    2024年02月06日
    浏览(41)
  • 带你一步步实现低代码开发平台——概述、实现模式、整体框架

    低代码开发平台是一种开发工具,它允许用户使用图形界面和少量编码来创建应用程序。这种平台的目的是加快应用程序开发速度,减少开发成本和技能门槛。目前,市场上有许多低代码开发平台可供选择,包括Microsoft Power Apps、OutSystems、Mendix等等。这些平台提供了各种各样

    2024年02月09日
    浏览(49)
  • 一个简单的DNS服务器

    DNS数据包的格式如下: 头部:会话标识ID,用于标识报文的ID标识,对于请求报文和其对应的应答报文,这个字段是相同的,通过它可以区分DNS应答报文是哪个请求的响应。 正文: Queries区域 查询名QNAME:要查找的名字,是一个或多个标识符的序列。 查询类型QTYPE:每一个问

    2024年02月09日
    浏览(34)
  • 从零开始搭建游戏服务器 第一节 创建一个简单的服务器架构

    由于现在java web太卷了,所以各位同行可以考虑换一个赛道,做游戏还是很开心的。 本篇教程给新人用于学习游戏服务器的基本知识,给新人们一些学习方向,有什么错误的地方欢迎各位同行进行讨论。 本篇教程预计使用Java+Redis+Mongo 本着先完成再完美的原则,从最简单的

    2024年02月10日
    浏览(40)
  • 使用nginx简单搭建一个ChatGPT代理服务器

    作者:ChenZhen 本人不常看CSDN消息,有问题通过下面的方式联系: 邮箱:1583296383@qq.com vx: ChenZhen_7 我的个人博客地址:https://www.chenzhen.space/🌐 版权:本文为博主的原创文章,本文版权归作者所有,转载请附上原文出处链接及本声明。📝 如果对你有帮助,请给一个小小的sta

    2024年02月06日
    浏览(32)
  • 在Linux服务器上简单部署一个Python项目

    一、在对应的服务器上检查有无Python环境 二、在服务器上创建对应项目的文件 三、收集项目的依赖包 四、将项目拷贝到服务器 五、创建Python运行的虚拟环境,并启动 六、安装对应项目的依赖包 七、运行主程序文件 以上就是在Linux上简单部署一个python项目的方法。

    2024年02月12日
    浏览(33)
  • C语言-写一个简单的Web服务器(三)

    上次我们研究了如何将解析web前端的请求,本次内容里我们将服务器的内容响应到前端,让浏览器展示。 服务器将数据响应到前端有其必要的返回数据,其结构如下,中间rn为换行,这个在不同系统(window,linux)不同,暂时将其作为一种固定格式。 在这里插入代码片 “

    2024年03月16日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包