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

Node.js中for循环遍历WebDAV createReadStream下载空文件问题

问题根因
  • 循环使用var声明变量存在变量提升问题,异步执行时fileName会被覆盖为最后一次循环的值,导致大部分读流请求的路径错误。
  • getDirectoryContents返回结果同时包含文件和子目录,未做类型判断直接对目录创建读流,会返回空内容。
  • 同时发起大量并发读流请求,超过SFCC WebDAV默认的并发连接限制,服务器会主动拒绝多数请求,返回空数据。
  • 未监听流的完成/错误事件,无法感知请求执行状态,可能出现连接提前释放、传输未完成的情况。
修正后的代码
let fs = require('fs');
let { createClient } = require("webdav");

// 将流下载封装为Promise,方便异步控制
function downloadFile(client, remoteFileName, localPath) {
  return new Promise((resolve, reject) => {
    const readStream = client.createReadStream(remoteFileName);
    const writeStream = fs.createWriteStream(localPath + remoteFileName);
    readStream.pipe(writeStream);
    // 监听完成和错误事件
    writeStream.on('finish', () => resolve(`下载完成:${remoteFileName}`));
    readStream.on('error', (err) => reject(`下载失败${remoteFileName}:${err.message}`));
    writeStream.on('error', (err) => reject(`写入失败${remoteFileName}:${err.message}`));
  });
}

let client = createClient(
  "https://../demandware.servlet/webdav/Sites/Logs",
  {
    username: "*",
    password: "*"
  }
);

client
.getDirectoryContents("/")
.then(async function(contents) {
  const localBasePath = "C:/Users/../Documents/COE/../logs/";
  // 顺序下载,控制并发避免触发服务器限制
  for (let item of contents) {
    // 只处理文件类型,跳过子目录
    if (item.type === 'file') {
      try {
        const res = await downloadFile(client, item.filename, localBasePath);
        console.log(res);
      } catch (err) {
        console.error(err);
      }
    }
  }
});
核心修改点
  • 把var替换为let,结合for...of循环利用块级作用域,保证每次循环的文件参数正确。
  • 增加文件类型判断,跳过子目录避免无效请求。
  • 封装Promise控制下载流程,采用顺序下载的方式避免触发SFCC WebDAV的并发限制。
  • 增加流事件监听,可感知每个文件的下载状态,避免传输未完成就释放资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 15:39:03