首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Node.js 實現圖片異步上傳:FormData + Formidable 完整方案

     編輯:Java 綜合教學

Node.js 實現圖片異步上傳:FormData + Formidable 完整方案

本文演示如何在 Node.js + Express + MongoDB 架構下,利用 HTML5 FormData 實現圖片異步上傳,並嵌入 Markdown 編輯器,後端使用 formidable 處理 multipart/form-data 解析與落盤。

前端:HTML (Jade 模板)

form#uploadfile
  div.form-group
    input#inputfile(type="file" name="inputfile")
    p.help-block#upfiletip 只支持 png 和 jpg 格式的圖片上傳
    button.btn.btn-success(type="button" onclick="upFile()") 上傳

前端:JavaScript (AJAX 上傳核心)

// 校驗副檔名
function judgePhotoExt(name) {
    if (!name.length) { showTip("你沒有選擇任何圖片!!!"); return false; }
    var ext = name.substring(name.lastIndexOf('.')).toLowerCase();
    if (ext !== '.png' && ext !== '.jpg' && ext !== '.jpeg') {
        showTip("只支持 png 和 jpg 格式!!!"); return false;
    }
    return true;
}

// 異步上傳
function upFile() {
    var filename = $("#inputfile").val();
    if (!judgePhotoExt(filename)) return;

    var formData = new FormData();
    var files = $("#inputfile")[0].files;
    if (files.length) formData.append("file", files[0]);

    $.ajax({
        url: '/blog/photo/new',
        type: 'POST',
        data: formData,
        async: false,          // 同步上傳,等待返回 URL 嵌入編輯器
        cache: false,
        contentType: false,    // 關鍵:禁止 jQuery 設置 Content-Type,讓瀏覽器自動生成 boundary
        processData: false,    // 關鍵:禁止 jQuery 將 FormData 序列化為字串
        success: function(url) {
            var txt = $("#content-textarea").val();
            $("#content-textarea").val(txt + "![圖片](" + url + ")");
            $('#imageModal').modal('hide');
        },
        error: function(err) { console.log(err); }
    });
}

關鍵點:contentType: false + processData: false 確保瀏覽器正確發送 multipart/form-data; boundary=---- 請求體。

FormData 進階用法

var oMyForm = new FormData();
oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456);        // 數字自動轉字串
oMyForm.append("userfile", fileInput.files[0]); // 文件對象
var oBlob = new Blob(["hey!"], {type: "text/xml"});
oMyForm.append("webmasterfile", oBlob);      // Blob 對象

var xhr = new XMLHttpRequest();
xhr.open("POST", "https://foo.com/submitform.php");
xhr.send(oMyForm);

後端:Express 路由 + Formidable

const formidable = require('formidable');
const fs = require('fs');
const uuid = require('uuid');

router.post('/photo/new', (req, res) => {
    const form = new formidable.IncomingForm();
    form.uploadDir = UPLOAD_PATH;        // 臨時目錄
    form.keepExtensions = true;          // 保留副檔名
    form.maxFieldsSize = 4 * 1024 * 1024; // 4MB 限制

    form.parse(req, (err, fields, files) => {
        if (err) return res.send("上傳失敗");

        let urls = [];
        for (let key in files) {
            let file = files[key];
            let ext = '';
            switch (file.type) {
                case 'image/pjpeg':
                case 'image/jpeg': ext = 'jpg'; break;
                case 'image/png':
                case 'image/x-png': ext = 'png'; break;
            }
            if (!ext) return res.send("只支持 png 和 jpg 格式");

            let saveName = uuid.v1() + '.' + ext;
            let savePath = form.uploadDir + saveName;
            urls.push(PHOTO_URL + saveName);

            fs.renameSync(file.path, savePath); // 移動到永久目錄
        }
        res.send(urls[0]); // 返回訪問 URL
    });
});

總結

  • FormData 實現零依賴的異步文件構造,配合 contentType/processData: false 繞過 jQuery 默認序列化。
  • formidable 簡化 Node 端 multipart 解析,支援大文件流式寫入臨時目錄再重命名。
  • 前端校驗副檔名 + 後端校驗 MIME 雙重保障安全。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved