Skip to content

实现文件上传功能通常涉及 前端后端 两部分:

  • 前端 负责提供上传界面(使用 HTML、JavaScript)。
  • 后端 处理文件存储(可以使用 Node.js、Python、PHP、Java 等)。

1. 前端实现文件上传

(1)使用 <input type="file">

HTML5 提供了 <input type="file"> 供用户选择文件:

html
<input type="file" id="fileInput">
<button onclick="uploadFile()">上传</button>

(2)使用 JavaScript 处理文件上传

JavaScript 可用 FormData 将文件发送到后端:

javascript
function uploadFile() {
    let fileInput = document.getElementById("fileInput");
    let file = fileInput.files[0];

    if (!file) {
        alert("请选择一个文件");
        return;
    }

    let formData = new FormData();
    formData.append("file", file);

    fetch("/upload", {
        method: "POST",
        body: formData
    })
    .then(response => response.json())
    .then(data => alert("上传成功: " + data.filename))
    .catch(error => alert("上传失败: " + error));
}

2. 后端实现文件上传

(1)Node.js(使用 Express & Multer)

Multer 是一个处理 multipart/form-data(即文件上传)的中间件。

安装依赖

bash
npm install express multer cors

实现文件上传 API

javascript
const express = require("express");
const multer = require("multer");
const cors = require("cors");

const app = express();
app.use(cors());

// 配置 Multer 存储
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, "uploads/"); // 存储到 "uploads" 目录
    },
    filename: (req, file, cb) => {
        cb(null, Date.now() + "-" + file.originalname); // 防止重名
    }
});
const upload = multer({ storage: storage });

// 处理文件上传请求
app.post("/upload", upload.single("file"), (req, res) => {
    res.json({ filename: req.file.filename });
});

// 服务器监听端口
app.listen(3000, () => console.log("服务器运行在 http://localhost:3000"));

目录结构:

/uploads          <-- 存放上传的文件
server.js        <-- 服务器代码

(2)Python(使用 Flask)

安装 Flask & Flask-CORS

bash
pip install flask flask-cors

实现文件上传 API

python
from flask import Flask, request, jsonify
from flask_cors import CORS
import os

app = Flask(__name__)
CORS(app)

UPLOAD_FOLDER = "uploads"
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return jsonify({"error": "没有选择文件"}), 400
    
    file = request.files['file']
    filename = file.filename
    file.save(os.path.join(UPLOAD_FOLDER, filename))
    
    return jsonify({"filename": filename})

if __name__ == '__main__':
    app.run(port=5000)

3. 限制文件大小 & 类型

为了安全性,建议 限制上传的文件大小允许的文件类型

(1)Node.js 限制文件

修改 Multer 配置:

javascript
const upload = multer({
    storage: storage,
    limits: { fileSize: 5 * 1024 * 1024 }, // 限制 5MB
    fileFilter: (req, file, cb) => {
        const allowedTypes = ["image/jpeg", "image/png", "application/pdf"];
        if (!allowedTypes.includes(file.mimetype)) {
            return cb(new Error("只允许上传 JPG, PNG, PDF"), false);
        }
        cb(null, true);
    }
});

(2)Python 限制文件

修改 Flask 代码:

python
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'pdf'}

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return jsonify({"error": "没有选择文件"}), 400
    
    file = request.files['file']
    if not allowed_file(file.filename):
        return jsonify({"error": "文件类型不允许"}), 400
    
    filename = file.filename
    file.save(os.path.join(UPLOAD_FOLDER, filename))
    
    return jsonify({"filename": filename})

4. 展示已上传的文件

前端获取已上传文件

javascript
function getUploadedFiles() {
    fetch("/files")
    .then(response => response.json())
    .then(files => {
        let fileList = document.getElementById("fileList");
        fileList.innerHTML = files.map(file => `<li>${file}</li>`).join("");
    });
}

后端返回文件列表

Node.js

javascript
const fs = require("fs");
app.get("/files", (req, res) => {
    fs.readdir("uploads", (err, files) => {
        res.json(files);
    });
});

Python

python
@app.route('/files', methods=['GET'])
def list_files():
    files = os.listdir(UPLOAD_FOLDER)
    return jsonify(files)

5. 进阶优化

使用 Cloud Storage(如 AWS S3、Google Cloud Storage)
支持多文件上传(multiple 属性)
添加进度条显示上传进度
提供文件删除功能


总结

步骤前端后端
文件选择<input type="file">-
文件上传fetch(FormData)multer / Flask request.files
文件存储-uploads/ 目录
安全性限制文件大小/类型限制 fileSize、文件类型
文件列表fetch("/files")fs.readdir() / os.listdir()

评论区

欢迎留言、补充或勘误。

xiaoba.blog