2

目录~~

知识储备

Multer

基本认识

Multer 是一个 node.js 中间件,用于处理multipart/form-data类型的表单数据,它主要用于上传文件。它是写在busboy之上非常高效。

注意: Multer 不会处理任何非multipart/form-data类型的表单数据。

安装方式
$ npm install --save multer
使用

Multer 会添加一个body对象 以及filefiles对象 到 express 的request对象中。body对象包含表单的文本域信息,filefiles对象包含对象表单上传的文件信息。

app.post('/profile', upload.single('avatar'), function (req, res, next) {
 // req.file 是 `avatar` 文件的信息
 // req.body 将具有文本域数据,如果存在的话
})

app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
 // req.files 是 `photos` 文件数组的信息
 // req.body 将具有文本域数据,如果存在的话
})

var cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
 // req.files 是一个对象 (String -> Array) 键是文件名,值是文件数组
 //
 // 例如:
 //  req.files['avatar'][0] -> File
 //  req.files['gallery'] -> Array
 //
 // req.body 将具有文本域数据,如果存在的话
})

如果你需要处理一个只有文本域的表单,你应当使用.none():

var express = require('express')
var app = express()
var multer  = require('multer')
var upload = multer()

app.post('/profile', upload.none(), function (req, res, next) {
 // req.body 包含文本域
})
multer(opts)

Multer 接受一个 options 对象,其中最基本的是dest属性,这将告诉 Multer 将上传文件保存在哪。如果你省略 options 对象,这些文件将保存在内存中,永远不会写入磁盘。
为了避免命名冲突,Multer 会修改上传的文件名。这个重命名功能可以根据您的需要定制。

以下是可以传递给 Multer 的选项。
一般只设置

var upload = multer({ dest: 'uploads/' })
两个个常用的api

里面接受的文件名,都是以input里name属性规定的属性值

.single(fieldname)

接受一个以fieldname命名的文件。这个文件的信息保存在req.file

.array(fieldname[, maxCount])

接受一个以fieldname命名的文件数组。可以配置maxCount来限制上传的最大数量。这些文件的信息保存在req.files

错误处理机制
var multer = require('multer')
var upload = multer().single('avatar')

app.post('/profile', function (req, res) {
  upload(req, res, function (err) {
    if (err instanceof multer.MulterError) {
      // 发生错误
    } else if (err) {
      // 发生错误
    }

    // 一切都好
  })
})
实例
后端逻辑
const express = require('express');
const multer = require('multer');
const fs = require('fs');

const app = express();
//设置保存地址
upload = multer({
    dest: 'uploads'
})
// 设置最多只能上传三个 files是input的name属性的值
upload_middle = upload.array('files', 3)

app.get('/index', async (req, res) => {
    const form = await fs.readFileSync('./index.html', {
        encoding: 'utf8'
    });
    res.send(form);
})
app.get('/axios', async (req, res) => {
    const form = await fs.readFileSync('./axios.html', {
        encoding: 'utf8'
    });
    res.send(form);
})
// app.post('/upload',upload.array('files',3), async(req,res) => {
//     res.send("保存成功");
// })

app.post('/upload', function (req, res) {
    upload_middle(req, res, function (err) {
        if (err instanceof multer.MulterError) {
            // 发生错误
            res.send("上传失败,文件最多上传三个");
        } else {
            res.send("文件上传成功");
        }
    })
})


app.listen(3000, function () {
    console.log('服务器启动成功')
})
前端代码
  • 原生ajax请求
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ajax上传文件</title>
</head>

<body>
    <div id="div"></div>
    <form id="form">
        <input type="file" name="files" multiple accept=".jpg,">
        <input id="btn" type="button" value="确认上传">
    </form>

    <script>
        const btn = document.getElementById("btn");
        const form = document.getElementById("form");
        btn.onclick = function () {
            console.log(1);
            const formData = new FormData(form);
            // 获取数组第一个文件
            //files = formDate.get("files");
            // 返回数组  获取所有文件
            // files = formData.getAll("files");
            // console.log(files);

            const xhr = new XMLHttpRequest();
            xhr.open('post', 'http://localhost:3000/upload');
            xhr.send(formData);
            xhr.onload = function () {
                alert(xhr.responseText);
            }
            // xhr.onreadystatechange = function () {
            //     // 2 请求已经发送了
            //     // 3 已经接收到服务器端的部分数据了
            //     // 4 服务器端的响应数据已经接收完成
            //     console.log(xhr.readyState);
            //     // 对ajax状态码进行判断 如果状态码的值为4就代表数据已经接收完成了
            //     if (xhr.readyState == 4) {
            //         console.log(xhr.responseText);
            //     }
            // }

        }
    </script>
</body>

</html>
  • axios请求
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>axios上传文件</title>
</head>

<body>
    <div id="div"></div>
    <form id="form">
        <input type="file" name="files" multiple accept=".jpg,">
        <input id="btn" type="button" value="确认上传">
    </form>

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        const btn = document.getElementById("btn");
        const form = document.getElementById("form");
        btn.onclick = async function () {
            const formData = new FormData(form);
            const res = await axios.post('http://localhost:3000/upload',formData);
            if(res.data){
                alert(res.data)
            }
        }
    </script>
</body>

</html>

注意: 都是通过访问http://localhost:3000/axios或者http://localhost:3000/index获取到前端代码的,用其他端口或者其他域名有可能会遇到同源政策的错误



tiger
49 声望6 粉丝