Node.js Express请求GeoServer WFS获取ShapeZip返回文本无法打开
解决Express请求GeoServer WFS返回ShapeZip文件损坏的问题
嘿,我瞅你这代码的问题很明显——你用request模块请求二进制的ShapeZip文件时,默认把响应当成文本处理了,导致文件结构被破坏,自然打不开啦!
问题根源
request模块默认的encoding参数是utf8,它会把GeoServer返回的二进制zip数据转换成字符串。这时候你再用new Buffer(body)转回来,已经丢失了部分二进制信息,写入的文件肯定是损坏的。
修复方案
只需要给request请求加上encoding: null配置,让它直接返回二进制Buffer,然后直接写入文件就行。另外还有几个小细节要注意:
- 给文件名加上
.zip后缀,不然系统识别不了; - 提前创建下载目录,避免因为目录不存在报错;
- 最好检查响应状态码,确保请求成功;
- 用流的
pipe方法处理下载更高效,适合大文件。
修改后的完整代码
var express = require('express'); var router = express.Router(); var fs = require('fs'); var request = require("request"); var DOWNLOAD_DIR = './downloads/'; // 确保下载目录存在,递归创建多级目录 if (!fs.existsSync(DOWNLOAD_DIR)) { fs.mkdirSync(DOWNLOAD_DIR, { recursive: true }); } router.get('/', function(req, res, next) { var file_url = 'https://geo.gob.bo/geoserver/aasana/wfs?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&typeName=aerodromos&outputFormat=shape-zip'; var filePath = DOWNLOAD_DIR + 'aerodromos.zip'; // 用pipe方式直接流到文件,更简洁高效 request({ url: file_url, encoding: null }) .pipe(fs.createWriteStream(filePath)) .on('finish', () => { console.log('文件已成功下载到: ' + filePath); res.render('index', { title: 'descargado' }); }) .on('error', (err) => { console.error('下载过程出错:', err); res.status(500).send('下载失败,请稍后重试'); }); }); module.exports = router;
额外说明
如果你还是想用回调的方式处理,也可以这样写:
request({ url: file_url, encoding: null }, function(err, resp, body) { if (!err && resp.statusCode === 200) { fs.writeFile(filePath, body, (writeErr) => { if (writeErr) { console.error('写入文件失败:', writeErr); res.status(500).send('下载失败'); } else { console.log('文件已下载到 ' + filePath); res.render('index', { title: 'descargado' }); } }); } else { console.error('请求失败:', err || `状态码异常: ${resp.statusCode}`); res.status(500).send('下载失败'); } });
这样修改后,你应该就能正常下载并打开ShapeZip文件了!
内容的提问来源于stack exchange,提问作者Dantmaur
相关产品推荐
相关产品推荐

