Node.js下载文件损坏求助:Windows平台文件大小异常
Node.js下载文件损坏、大小异常的解决方案
Hey,我看你用Node.js下载文件时碰到了文件变大(185KB vs 原文件113KB)、还没法在Photoshop打开的问题,这大概率是没处理HTTP重定向或者流操作的逻辑/错误处理缺失导致的,我来帮你分析并修复:
问题背后的原因
- 未处理重定向:很多下载链接会返回301/302重定向,你的两段代码都没自动跟随重定向,结果下载到的可能是重跳转的HTML页面,而不是实际的文件——这就是文件变大且损坏的核心原因。
- 缺失错误处理:原代码完全没监听请求或写入时的错误,一旦过程中出问题,会直接导致文件写入不完整或者混入无效数据。
- 第二段代码的流关闭逻辑错误:
file.close(cb)和file.end()的顺序搞反了,而且close的回调处理也不对,容易导致写入异常。
修复后的代码方案
方案1:用request库(省心处理重定向+错误捕获)
request默认支持跟随重定向,只要补上fs引入和错误处理就行:
const request = require('request'); const fs = require('fs'); function download(url, dest, cb) { // 显式开启重定向(默认已开,但写出来更清晰) request({ url, followRedirect: true }) .on('response', (res) => { if (res.statusCode !== 200) { cb(new Error(`请求失败,状态码:${res.statusCode}`)); } }) .pipe(fs.createWriteStream(dest)) .on('error', (err) => { // 写入失败时删掉损坏的文件 fs.unlink(dest, () => {}); cb(err); }) .on('close', () => { cb(null); // 下载完成,无错误 }); }
方案2:用原生https模块(手动处理重定向+正确流操作)
原生模块需要自己处理重定向,同时修正流的关闭逻辑:
const https = require('https'); const fs = require('fs'); const { URL } = require('url'); function download(url, dest, cb) { const fetch = (currentUrl) => { https.get(currentUrl, (response) => { // 处理3xx重定向 if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) { const redirectUrl = new URL(response.headers.location, currentUrl).href; return fetch(redirectUrl); } if (response.statusCode !== 200) { return cb(new Error(`请求失败,状态码:${response.statusCode}`)); } const file = fs.createWriteStream(dest); response.pipe(file); file.on('error', (err) => { fs.unlink(dest, () => {}); cb(err); }); file.on('finish', () => { // 先结束写入,再关闭文件并调用回调 file.close(() => cb(null)); }); }).on('error', (err) => cb(err)); }; fetch(url); }
额外小建议
- 下载完成后可以对比文件的MD5/SHA哈希值,确认和原文件完全一致,避免隐性的文件损坏。
- 如果是超大文件,可以考虑添加进度监听,同时调整流的
highWaterMark参数优化性能(默认值一般够用)。
内容的提问来源于stack exchange,提问作者madha kumar
相关产品推荐
相关产品推荐

