vue、nodejs上传图片

演示

演示.gif

技术栈

  • 前端:Vue
  • 后端:nodejs、express、multer

本地端口

  • 前端:8080
  • nodejs:3000
  • nginx:3001

前端部分

<script>
    import axios from "@/axios";
    export default {
        data() {
            return {
                imgs: [] //已上传图片列表
            };
        },
        methods: {
            fileChange(e) {
                // 获取file文件
                const file = e.target.files[0];
                if (file.size / 1024 / 1024 > 5) {
                    alert("图片大于5M上传失败");
                    return;
                }
                // 通过FormData进行接口传输
                const formData = new FormData();
                formData.append("imgFile", file);
                // 接口上传
                axios.uploadImg(formData).then(response => {
                    if (response.code == 200) {
                        // 1、通过base64 预览
                        // let reader = new FileReader();
                        // reader.readAsDataURL(file);
                        // reader.onload = e => {
                        //     this.imgs.push(e.target.result);
                        // };
                        // 2、这里通过接口返回图片地址预览
                        this.imgs.push("//localhost:3001" + response.data);
                    }
                });
            }
        }
    };
</script>
<template>
    <div>
        <div class="photo">
            <div v-for="(img,index) in imgs" :key="index">
                <img class="upload-img" :src="img" alt />
            </div>
            <div class="default">
                <img src="@/assets/img/img_photo.png" alt />
                <input type="file" name="file" accept="image/*" @change="fileChange($event)" />
            </div>
        </div>
    </div>
</template>

axios.js

import axios from "axios";
const instance = axios.create();
axios.defaults.withCredentials = true;
//请求拦截器
instance.interceptors.request.use(
    config => {
        return config;
    },
    error => {
        return Promise.reject(error);
    }
);
//响应拦截器
instance.interceptors.response.use(
    response => {
        return Promise.resolve(response.data);
    },
    error => {
        return Promise.reject(error);
    }
);
export default {
    //上传图片
    uploadImg: data => {
        return instance.post("//localhost:3000/upload", data);
    }
};

流程:

  1. 通过input的onchange事件获取到本地图片文件。
  2. 调用接口传输FormData格式的图片文件。
  3. 拿到接口返回的服务器图片地址进行预览。

后端部分

const express = require('express')
const upload = require("../lib/upload");
const app = express();

// .single(fieldname)
// 接受一个以 fieldname 命名的文件。这个文件的信息保存在 req.file。
app.post('/upload', upload.single("imgFile"), function (req, res, next) {
    res.json({
        code: 200,
        data: "/" + req.file.filename,
        msg: "success"
    });
})

/lib/upload.js

const multer = require("multer");

const upload = multer({
    storage: multer.diskStorage({
        destination: "/uploads", //本地保存的目录(E:\uploads)
        filename: function(req, file, cb) {
            //保存的文件名
            cb(null, file.fieldname + "-" + Date.now() + "-" + file.originalname);
        }
    }),
    //限制上传大小5M和同时上传的数量
    limits: {
        fileSize: 1024 * 1024 * 5,
        files: 5
    },
    //依据mime文件类型过滤
    fileFilter: function(req, file, cb) {
        const allowArr = ["image/jpeg", "image/gif", "image/png"];
        if (allowArr.indexOf(file.mimetype) > -1) {
            cb(null, true);
        } else {
            cb(new Error("文件类型不正确"));
        }
    }
});

module.exports = upload;

当前端调用"/upload",在multer中间件,我们自定义了保存的目录、文件名,同时限制了大小、数量和文件类型。

最后返回给前端的数据data中,是一个自定义后的文件名。

为了让前端访问到保存后的文件,使用了nginx做代理。

Nginx代理

nginx.conf

server {
    listen       3001;
    server_name  localhost;
    location / {
        root   E:\uploads;
    }
}

代理的端口是3001,目录是我们自定义的保存目录"E:\uploads"。

这样前端<img>标签的src设置为"localhost:3001+图片名",就可以显示图片了。

后会有期。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容