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

Chrome扩展能否重命名正在下载的文件?附现有批量下载代码

问题

开发了一款Chrome扩展,通过向当前标签页注入JS模拟点击操作,批量下载PDF及EDI文件,目前已实现配置传递与注入执行的完整流程,但下载的文件名杂乱难以管理。曾尝试用外部Python脚本实时处理已下载文件,不够便捷且多进程运行对用户不友好,希望通过Chrome扩展实现下载时或下载前重命名文件。


解决方案

核心思路是利用Chrome扩展的downloadsAPI拦截下载请求,或直接通过API发起下载并指定自定义文件名,替代原有的模拟点击下载逻辑。

1. 配置扩展权限

修改manifest.json,添加必要权限以支持下载控制:

{
  "manifest_version": 3,
  "permissions": ["downloads", "scripting", "storage", "tabs"],
  "host_permissions": ["<all_urls>"], // 替换为目标网站的具体域名更安全
  "background": {
    "service_worker": "background.js"
  },
  // 保留原有扩展配置(如popup、图标等)
}

2. 后台脚本拦截并修改下载请求

新建background.js,用于监听下载事件并执行重命名:

// 存储待重命名的文件映射(URL -> 目标文件名)
const pendingRenames = new Map();

// 监听下载创建事件,触发重命名
chrome.downloads.onCreated.addListener(downloadItem => {
  const targetFilename = pendingRenames.get(downloadItem.url);
  if (targetFilename) {
    chrome.downloads.update(downloadItem.id, { filename: targetFilename });
    pendingRenames.delete(downloadItem.url);
  }
});

// 接收注入脚本的重命名准备请求
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === "prepareRename") {
    pendingRenames.set(request.url, request.filename);
    sendResponse({ success: true });
  }
});

3. 修改注入脚本(getPagesSource.js)的下载逻辑

不再模拟点击下载按钮,改为提取实际下载链接并通知后台准备重命名:

async function downloadFiles(document_root) {
  // 保留原有循环、筛选、弹窗打开等逻辑...

  // 替换原模拟点击EDI下载的代码
  if (conf_edi) {
    // 提取EDI下载链接(根据页面实际结构调整选择器)
    const ediLink = document_root.querySelector("#uikit-root > div > div.modal-dialog.modal-xl > div > div.modal-header > div.modal-header-buttons > div.dropdown.btn-group.open > ul > li > a");
    const ediUrl = ediLink.href;
    // 获取用于生成文件名的标识(如订单号、类型)
    const orderNumber = document_root.querySelector(`#root > div > div.ApplicationLayoutBody.has-footer > div > div > div:nth-child(4) > div:nth-child(1) > table > tbody > tr:nth-child(${i}) > td:nth-child(2)`).innerText;
    const targetEdiName = `[${span || "Normal"}] ${orderNumber}.edi`;

    // 通知后台准备重命名
    await chrome.runtime.sendMessage({
      action: "prepareRename",
      url: ediUrl,
      filename: targetEdiName
    });
    // 发起下载
    window.open(ediUrl, "_blank");
  }

  // 替换原模拟点击PDF下载的代码
  if (conf_pdf) {
    const pdfLink = document_root.querySelector("#uikit-root > div > div.modal-dialog.modal-xl > div > div.modal-header > div.modal-header-buttons > div.dropdown.btn-group:nth-child(2).open > ul > li > a");
    const pdfUrl = pdfLink.href;
    const orderNumber = document_root.querySelector(`#root > div > div.ApplicationLayoutBody.has-footer > div > div > div:nth-child(4) > div:nth-child(1) > table > tbody > tr:nth-child(${i}) > td:nth-child(2)`).innerText;
    const targetPdfName = `[${span || "Normal"}] ${orderNumber}.pdf`;

    await chrome.runtime.sendMessage({
      action: "prepareRename",
      url: pdfUrl,
      filename: targetPdfName
    });
    window.open(pdfUrl, "_blank");
  }

  // 保留原有弹窗关闭、计数更新等逻辑...
}

4. 替代方案:直接用API发起下载

如果能直接获取文件内容或稳定下载链接,可跳过拦截,直接在后台发起下载:

// 在background.js中添加下载处理逻辑
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === "downloadDirectly") {
    chrome.downloads.download({
      url: request.url,
      filename: request.filename,
      saveAs: false
    }, downloadId => {
      sendResponse({
        success: !chrome.runtime.lastError,
        error: chrome.runtime.lastError?.message
      });
    });
    return true; // 保持消息通道异步响应
  }
});

// 在注入脚本中调用
await chrome.runtime.sendMessage({
  action: "downloadDirectly",
  url: fileUrl,
  filename: targetFilename
});

关键注意事项

  • 提取真实下载链接:需根据页面实际DOM结构调整选择器,若链接为动态生成,可监听页面的XHR/fetch请求获取真实地址。
  • 文件名唯一性:生成文件名时建议添加时间戳或序号,避免文件覆盖。
  • 权限限制:确保host_permissions覆盖目标网站域名,避免跨域权限问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:45:31