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
相关产品推荐
相关产品推荐

