使用axios、nodejs、express、multer进行前后端图片互传

481 阅读1分钟

图片上传

前端

选择图片

使用 type="file"input 标签来进行图片的选择,给该元素的 onchange 事件(图片选择完成后触发)绑定一个回调函数。这里与事件绑定的回调函数作用是在img标签中展示选中的图片。

<body>
    <input class="fileInp" type="file" name="img" onchange='fileSelected()' accept="image/*">
    <!--在页面展示选中的图片-->
    <img src="" width="120" />
</body>
<script>
    //图片选中并加载完成时调用的函数,目的是在页面中展示选中的图片
    function fileSelected() {
        //file对象只获取到了对文件的描述信息,但没有获得文件中的数据。
        //我们可以通过html5提供的FileReader读取到文件中的数据
        let reader = new FileReader()
        let my_img = document.querySelector(".fileInp").files[0];
        // 调用reader.readAsDataURL()方法,把图片转成base64
        reader.readAsDataURL(my_img);
        // 监听reader对象的的onload事件,当图片加载完成时,把base64编码賦值给预览图片
         reader.addEventListener("load", function () {
            document.getElementsByTagName("img")[0].src = reader.result;
        }, false);
    }
</script>

FileReader的介绍

上传图片

给button的onclick事件绑定回调函数。该回调函数主要是向后端发送图片。

<body>
    <button onclick="submit()">提交</button>
</body>
<script>
    function submit() {
        //form-data格式一般是用来进行文件上传的
        //创建一个新的"FormData"对象。
        let fd = new FormData()
        //通过FormData.append()向FormData中添加文件
        fd.append("file", document.querySelector(".fileInp").files[0])
        //使用axios向后端发送请求
        axios.post('http://127.0.0.1:8000/img', fd, {
            headers: {
            //设置发送的类型
                "Content-Type": "multipart/form-data "
            }
        }).then(res => {
            console.log(res, 'res');
        })
    }
</script>

FormData的介绍

总体代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <input class="fileInp" type="file" name="img" onchange='fileSelected()' accept="image/*">
    <!--在页面展示选中的图片-->
    <img src="" width="120" />
    <button onclick="submit()">提交</button>
</body>
<script src="./public/js/axios.js"></script>
<script>
    //图片选中并加载完成时调用的函数,目的是在页面中展示选中的图片
    function fileSelected() {
        //file对象只获取到了对文件的描述信息,但没有获得文件中的数据。
        //我们可以通过html5提供的FileReader读取到文件中的数据
        let reader = new FileReader()
        let my_img = document.querySelector(".fileInp").files[0];
        // 调用reader.readAsDataURL()方法,把图片转成base64
        reader.readAsDataURL(my_img);
        // 监听reader对象的的onload事件,当图片加载完成时,把base64编码賦值给预览图片
         reader.addEventListener("load", function () {
            document.getElementsByTagName("img")[0].src = reader.result;
        }, false);
    }
    
    function submit() {
        //form-data格式一般是用来进行文件上传的
        //创建一个新的"FormData"对象。
        let fd = new FormData()
        //通过FormData.append()向FormData中添加文件
        fd.append("file", document.querySelector(".fileInp").files[0])
        //使用axios向后端发送请求
        axios.post('http://127.0.0.1:8000/img', fd, {
            headers: {
                //设置发送的类型
                "Content-Type": "multipart/form-data "
            }
        }).then(res => {
            console.log(res, 'res');
        })
    }
</script>

</html>

后端

//npm i express 下载并引入express
const express = require('express');
const path = require('path')
//npm i cors 下载并引入cors解决跨域
const cors = require('cors')
const fs = require('fs')
//npm i multer 下载并引入multer
//Multer 是一个 node.js 中间件,用于处理 `multipart/form-data` 类型的表单数据,它主要用于上传文件。
const multer = require('multer');
const app = express();
app.use(cors())

// 指定上传的文件路径  //这里是当前文件平级的public/images
const upload = multer({ dest: path.join(__dirname, 'public', 'images') });

//upload.single()的参数需要是fd中添加的属性名
app.post('/img', upload.single('file'), (req, res) => {
    let fileObj = req.file;
    //获取类型
    let filetype = fileObj.originalname.split('.').pop();
    let imgUrl = fileObj.filename + '.' + filetype;
    //使用fs模块写入图片
    fs.rename(__dirname + '\\public\\images\\' + fileObj.filename,
              __dirname + '\\public\\images\\' + imgUrl,
              function (err) {
                  if (!err) {
                      console.log('成功!');
                  } else {
                      throw (err);
                  }
    })
    res.send('ok')
})
const port = 8000;
app.listen(port, () => {
    console.log("开始监听");
});

Multer的介绍及使用

图片获取

前端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        img {
            width: 300px;
        }
    </style>
</head>

<body>
    <img src="">
</body>
<script src="./public/js/axios.js"></script>
<script>
    function getImg() {
    //先获取文字信息
        axios.get("http://127.0.0.1:8000/info").then(res => {
            //请求图片
            axios.request({
                url: "http://127.0.0.1:8000/img",
                //这里最重要,不要去掉,指定响应类型
                responseType: 'blob',  
                method: 'get'
            }).then(res => {
                //Blob对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取
                let blob = new Blob([res.data], { type: "image/png" });
                //创建url
                let url = window.URL.createObjectURL(blob);
                document.getElementsByTagName("img")[0].src = url;
            })
        })
    }
    getImg();
</script>

</html>

Blob的介绍

后端

app.get('/info', (req, res) => {
    res.send({ 'message': "ok" });
})
app.get('/img', (req, res) => {
    res.sendFile(__dirname + "/" + `/public/images/图片名`);
})

图片名可以在前端发送axios的时候带上,然后在后端读取图片名