Node.js文件下载为空问题求助:如何正确实现文件下载?
文件下载后为空(0kb)的排查与解决
我正尝试编写Node.js脚本从网站获取文件,预期流程如下:
- 从CSV文件中获取下载链接(多链接时循环处理);
- 下载链接对应的文件;
- 将文件保存到本地。
我的代码运行无报错或警告,会输出正确的“Download completed - ”提示,指定路径也会生成新文件,但文件始终为空(0kb)。以下是我的代码:
const fs = require('fs'); const csv = require('csv'); const https = require('https'); const puppeteer = require('puppeteer'); const { parse } = require("csv-parse"); downloadAllFiles(); async function downloadAllFiles() { var FILE = //LOCATION OF THE CSV FILE; const parse = require('csv-parse/lib/sync'); const data = fs.readFileSync(FILE); let records = parse(data, {columns: false,}); //Here is some more code to login to the website. The connection is successful. await downloadFile(records[0][0], records[0][1]); }; function downloadFile(destinationPath, url) { return new Promise((resolve, reject) => { https.get(url, (response) => { let filePath = //WHERE TO SAVE THE FILE; let stream = fs.createWriteStream(filePath); response.on("error", reject); stream.on("finish", () => { stream.close(); console.log("Download Completed - " + url); resolve(); }).on("error", reject); response.pipe(stream); }).on("error", reject); }); };
可能的原因与解决办法
1. 下载请求未携带登录会话
你用Puppeteer完成了网站登录,但https.get发起的是独立HTTP请求,不会自动继承Puppeteer浏览器中的Cookie会话。如果目标文件需要登录权限才能访问,网站会返回空内容(或无数据的200响应),最终生成空文件。
解决步骤:
- 登录成功后从Puppeteer页面提取Cookie
- 将Cookie添加到
https.get的请求头中
修改后的代码片段:
async function downloadAllFiles() { var FILE = //LOCATION OF THE CSV FILE; const parse = require('csv-parse/lib/sync'); const data = fs.readFileSync(FILE); let records = parse(data, {columns: false,}); // 登录代码(已成功) const browser = await puppeteer.launch(); const page = await browser.newPage(); // ... 你的登录逻辑 ... // 提取页面Cookie const cookies = await page.cookies(); const cookieHeader = cookies.map(c => `${c.name}=${c.value}`).join('; '); // 传递Cookie到下载函数 await downloadFile(records[0][0], records[0][1], cookieHeader); await browser.close(); }; function downloadFile(destinationPath, url, cookieHeader) { return new Promise((resolve, reject) => { // 添加Cookie请求头 const options = { headers: { 'Cookie': cookieHeader } }; https.get(url, options, (response) => { // 使用传入的目标路径 let filePath = destinationPath; let stream = fs.createWriteStream(filePath); response.on("error", reject); stream.on("finish", () => { stream.close(); console.log("Download Completed - " + url); resolve(); }).on("error", reject); response.pipe(stream); }).on("error", reject); }); };
2. 未处理HTTP重定向
如果目标URL返回3xx状态码(比如302重定向),https.get默认不会自动跟随重定向,此时你拿到的是重定向响应而非实际文件内容,导致写入空文件。
解决步骤:
- 检查响应状态码,若为重定向则递归调用下载函数访问新地址
修改downloadFile中的响应处理逻辑:
https.get(url, options, (response) => { // 处理重定向 if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) { // 跟随重定向,处理相对路径 const redirectUrl = new URL(response.headers.location, url).href; return downloadFile(destinationPath, redirectUrl, cookieHeader).then(resolve).catch(reject); } // 原有的流处理代码... })
3. 未验证响应数据是否存在
可以临时添加日志,确认是否真的接收到了文件数据:
response.on('data', (chunk) => { console.log(`收到数据块,大小:${chunk.length}字节`); }); response.on('end', () => { console.log('响应结束'); });
如果没有触发data事件,说明请求未获取到有效数据,需重点排查会话权限或URL有效性。
4. 文件路径未正确赋值
确认代码中let filePath = //WHERE TO SAVE THE FILE;已替换为实际路径,比如直接使用传入的destinationPath,避免写入错误路径或未初始化的空路径。
内容的提问来源于stack exchange,提问作者SuperRamen
相关产品推荐
相关产品推荐

