You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+Express服务端如何获取POST上传的GeoJSON文件?

解决Express服务端无法获取上传文件的方案

核心问题是Express默认不处理multipart/form-data类型的请求(文件上传必须用这个类型),需要借助multer中间件来解析上传的文件数据,以下是具体实现步骤:

1. 安装依赖

首先安装处理文件上传的multer包:

npm install multer

2. 前端表单修正

确保Pug表单的enctype属性设置为multipart/form-data,这是文件上传的必要配置:

form(method="POST", action="/upload", enctype="multipart/form-data")
  input(type="file", name="geoFile", accept=".json,.geojson,.gpkg,.tiff,.geotiff", onchange="fileChange(event)")
  button(type="submit") 上传文件

前端的fileChange方法只需做文件校验即可,无需手动保存文件:

function fileChange(event) {
  const file = event.target.files[0];
  if (!file) return;
  
  // 验证文件类型(可选)
  const allowedExts = ['.json', '.geojson', '.gpkg', '.tiff', '.geotiff'];
  const ext = file.name.slice(file.name.lastIndexOf('.')).toLowerCase();
  if (!allowedExts.includes(ext)) {
    alert('仅支持.json/.geojson/.gpkg/.tiff/.geotiff格式');
    event.target.value = '';
  }
}

3. 服务端路由配置

用multer配置内存存储(直接获取文件Buffer,适合存入MongoDB),并在路由中解析上传的文件:

const express = require('express');
const multer = require('multer');
const mongoose = require('mongoose');
const router = express.Router();

// 配置内存存储,直接读取文件Buffer
const storage = multer.memoryStorage();
const upload = multer({
  storage: storage,
  fileFilter: (req, file, cb) => {
    // 过滤允许的文件类型
    const allowedExts = ['.json', '.geojson', '.gpkg', '.tiff', '.geotiff'];
    const ext = file.originalname.slice(file.originalname.lastIndexOf('.')).toLowerCase();
    allowedExts.includes(ext) ? cb(null, true) : cb(new Error('不支持的文件类型'));
  }
});

// 单文件上传路由,参数对应前端input的name="geoFile"
router.post('/upload', upload.single('geoFile'), async (req, res) => {
  try {
    if (!req.file) return res.status(400).send('请选择要上传的文件');

    const { originalname, buffer, mimetype } = req.file;
    const fileExt = originalname.slice(originalname.lastIndexOf('.')).toLowerCase();

    let fileData;
    // 区分处理文本类和二进制类文件
    if (fileExt === '.json' || fileExt === '.geojson') {
      // GeoJSON/JSON解析为JSON对象
      fileData = JSON.parse(buffer.toString('utf8'));
    } else {
      // GPKG/GeoTIFF直接存Buffer,MongoDB自动转为BinData类型
      fileData = buffer;
    }

    // 存入MongoDB(假设已有对应的Model)
    const GeoFile = mongoose.model('GeoFile', new mongoose.Schema({
      filename: String,
      mimetype: String,
      data: mongoose.Schema.Types.Mixed // 兼容JSON和Buffer类型
    }));

    await new GeoFile({
      filename: originalname,
      mimetype: mimetype,
      data: fileData
    }).save();

    res.status(200).send('文件上传并保存成功');
  } catch (err) {
    console.error(err);
    res.status(500).send(`上传失败:${err.message}`);
  }
});

module.exports = router;

关键注意事项

  • 必须确保表单的enctype="multipart/form-data",否则文件数据不会被正确传递到服务端。
  • multer的upload.single('geoFile')参数要和前端input的name属性完全一致。
  • 二进制文件(如GeoTIFF)直接存Buffer即可,MongoDB会自动处理为适合存储的二进制类型,无需转字符串。

内容的提问来源于stack exchange,提问作者Lorano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 17:10:23