文章目录

  • 前言
  • 一、申请阿里云OSS
  • 二、Vue前端读取图片
  • 三、将图片base64转成二进制文件
  • 四、搭建express服务器
  • 五、通过axios给服务器发送请求
  • 六、发送图片并上传阿里云
    • 我们首先了解一下,要怎么发送图片给服务器
    • 我们把最终效果留到最后一起看,我们先看一下服务器那边的代码是什么样的
  • 总结

前言

上篇文章提到了如何用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的名称和地域的,这些都是后面非常重要的参数

3、如果是打算长期用的,不是说就尝试下能不能上传图片的,可以买个5块钱的套餐,不然传几张图片可能就给你服务停了
4、要把读写权限改成公共读写

如果以上的都没啥问题了,可以正式进入具体的代码实现了

二、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>

大概是长这个样子的

现在点击选择文件是可以从自己电脑上选择文件或图片的,那么读进来的图片我们要怎么处理呢

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

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

上面记得给src加:,不然接收到的是个内容为变量名的字符串

2、然后我们定义一个方法,当input的内容发生改变(也就是选择完图片)就触发该事件

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

我们随便选张图,看看效果

可以显示出来了!

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

我们可以打印看一下FileReader转换后的图片内容是咋样的,在对象fr的result里

我第一次看到这玩意的时候心里想的是,我的妈呀,这啥东西!
这是图片的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.lengthlet u8arr = new Uint8Array(n)while (n--) {u8arr[n] = bstr.charCodeAt(n)}let file = new File([u8arr], `${filename}.${suffix}`, {type: mime})return file
},

具体代码就不分析了,基本上都是这么写的,直接用就可以了,感兴趣的可以查下方法名的作用,一行行打印出来看看具体是什么,我这里就直接打印最终结果

这样前端的准备工作就完成了,接下来就是如何发送给服务器然后上传给阿里云

四、搭建express服务器

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

// app.js
const express = require('express');
const app = express();
const PORT = 3002app.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给服务器发送请求

上一篇博客如何封装一个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

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

我们打印看一下服务器返回了什么东西

就是我们第四节设置的服务器完整的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-ossconst 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也就是图片上传到阿里云

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


效果跟想像的没有区别,我上传了一张图片,然后能直接通过返回的阿里云url访问并显示该图片
打印出来的结果可以看到我发送图片的时间,可以去阿里云的文件夹下看下是否上传成功了

确实是在这个时间在该文件夹下上传了一张图片


总结

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

服务器代码,文件名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-ossconst 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><inputtype="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.lengthlet 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>

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

另外提一嘴,感觉保存在云端不是特别好的选择,还是保存在本地数据库里会比较好,我再学习下,如果网上没特别好的教程我考虑下一篇写这个,那么我们下一篇博客再见!

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

  1. 微信头像下载并上传到阿里云OSS,PHP文件上传到阿里云OSS简单代码(OSS文件上传,微信头像下载,CURL下载文件,微信头像链接过期)

    (就这么个小事,有多少公司多少项目没做到!!) 微信公众号项目,后端获取到授权用户的微信头像后,要自行下载保存,不下载的话,微信返回的头像链接会在一段时间后过期,无法访问! 下面是我写的两个简单实用方 ...

  2. dockerfile构建一个(python+flask+html)镜像 + 上传到阿里云私有仓库 + 部署到k8s---全过程

    前言 因为之前根据一些网上的教程一个个部分实践过整个部署流程,但都是根据现有的程序/ymal文件等进行创建部署,未能根据自己特定的项目进行部署.因此,这篇博文,打算完整部署一个自己编写的python+ ...

  3. 亲测简单易懂可用:阿里云OSS入门实战2(集成到SpringBoot项目中存放用户头像)

    亲测简单易懂可用:阿里云OSS入门实战2(集成到SpringBoot项目中存放用户头像) 大噶好,我们继续延续上一章,学习如何使用OSS存放用户头像代码示例; 在application.propert ...

  4. 用go来搭建一个简单的图片上传网站

    提前说明一下:代码参考了<Go语言编程>,稍有变动, 自己亲自玩了一遍. 之前玩过go web server, 现在来用go来搭建一个简单的图片上传网站, 工作目录是:~/photoweb ...

  5. wangEditor自定义一个图片上传

    wangEditor上给了几种上传图片的方式,从简单到困难:[这边只给出前端代码] (1)上传图片的base64(可以用作练习) (2)自己配置接口服务器存图片(需求只能连接内网情况) (3)上传到阿 ...

  6. Python开发第一步:如何制作一个简单的桌面应用

    Python开发第一步:如何制作一个简单的桌面应用 前言 大家好,我是baifagg, 一个热爱Python的编程爱好者. 今天我们来学习一下, 如何用Python制作一个简单的桌面应用程序. 虽然桌 ...

  7. ipad php mysql_如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1

    原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个i ...

  8. node.js request get 请求怎么拿到返回的数据_从零开始用nodejs写一个简单的静态服务器

    nodejs搭建服务器第一步 const http = require("http")const PORT = 8000 const server = http.createSer ...

  9. ios php mysql实例_如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1

    原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个i ...

最新文章

  1. Java同一个类的不同实例_如何创建2个类实例注入不同类的依赖项实现(通过guice)?...
  2. html浏览位置坐标,HTML5教程 | HTML5地理定位(GeoLocation API)
  3. flipdim--按指定维数翻转矩阵
  4. 《A Berkeley View of systems challenges for AI》总结
  5. centos7+tomcat部署JavaWeb项目超详细步骤
  6. 八个被现代科学证实的古老信条
  7. PHP目前比较常见的五大运行模式
  8. Linux nm命令
  9. 基于SSM的图书馆管理系统,高质量毕业论文范例(可直接使用),项目导入视频,附送源码和数据库脚本,论文撰写教程
  10. Cognos函数(六) - total的使用
  11. [BZOJ3772]精神污染(主席树)
  12. Mac Chrome 访问证书有问题的https网站时无法忽略风险继续浏览
  13. 抱薪者说 | 在Conflux玩夺宝游戏是怎样的一种体验?
  14. Python之.loc与.iloc的用法
  15. [LINUX学习]sheel脚本循环KILL,并启动
  16. springboot集成netty实现代理服务器
  17. 【图像检索】DOLG论文
  18. 2019美研计算机录取,2019美研录取更新 | 哥伦比亚大学、芝加哥大学OFFER携手来袭...
  19. Java入门集合之Set集合(重写equals()和hashcode()方法)
  20. asio::streambuf的使用

热门文章

  1. webstorm运行html项目,webstorm如何运行-webstorm运行项目的方法
  2. python - 常用Excel模块
  3. 以下就是央国企数字化转型
  4. Revit二次开发——读取cad中的文字信息
  5. 用ftp上传到服务器视频文件夹,ftp 上传文件夹到服务器
  6. 关于pyecharts可视化地图中国经济、人口等数据
  7. css中@font-face的使用
  8. python人力成本数据测算_年度人力成本数据分析思维
  9. 2018 公开课盘点企业篇:十家企业带你看 AI 的实际应用成果及人才招聘需求...
  10. java libpcap,tcpreplay安装失败,libpcap / collect