google-chrome-extension - Chrome 扩展 - 如何访问本地文件 ://with manifest v3

标签 google-chrome-extension manifest.json

我有一个 Chrome 扩展程序,可以(如果您允许访问文件 URL)获取您在 chrome 中打开的本地 pdf 文件并将其发送到我们的 API 进行处理。这是通过使用 XMLHttpRequest 获取 pdf 来完成的。至file:///Users/user/whatever/testfile.pdf从后台脚本。
当为 Chrome 扩展迁移到 manifest v3 时,后台脚本将成为服务 worker 。仅在服务人员中 fetch可用,而不是 XMLHttpRequest .问题是,fetch 只支持 http 和 https,不支持 file://url。那么我怎样才能使 Chrome 扩展获取/获取本地文件的功能相同呢?
编辑:我也尝试过的事情:

  • 按照答案的建议,从注入(inject)的 iframe 生成 XMLHttpRequest。
    这会产生错误 net:ERR_UNKNOWN_URL_SCHEME提出请求时
    net:ERR_UNKNOWN_URL_SCHEME
  • 从注入(inject)的内容脚本制作 XMLHttpRequest。
    这会产生错误 Access to XMLHttpRequest at 'file:///.../testfile1.docx.pdf' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https. Access to XMLHttpRequest at 'file:///Users/clara.attermo/Downloads/testfile1.docx.pdf' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.

  • 根据我对 file:// 的大量研究访问的了解通常被阻止,Chrome 扩展后台脚本曾经是一个异常(exception)。在我看来,内容脚本或 Action 弹出窗口从未允许这样做。
    我的 manifest.json 供引用:
    {
      "manifest_version": 3,
      "name": "..",
      "version": "0.1",
      "icons": {
        "16": "assets/icon-16x16.png",
        "48": "assets/icon-48x48.png",
        "128": "assets/icon-128x128.png"
      },
      "action": {
        "default_title": ".."
      },
      "background": {
        "service_worker": "background.js"
      },
      "permissions": [
        "webRequest",
        "activeTab",
        "scripting",
        "storage",
        "unlimitedStorage",
        "identity",
        "pageCapture"
      ],
      "host_permissions": [
        "<all_urls>"
      ],
      "web_accessible_resources": [{
        "resources": ["iframe.html"],
        "matches": [],
        "extension_ids": []
      }]
    }
    
    内容脚本以编程方式注入(inject)(使用 webextension-polyfill 支持 promise )
    browser.action.onClicked.addListener(async (tab: Tab) => {
      await browser.scripting.executeScript({files: [ "inject.js" ], target: {tabId: tab.id}});
    });
    

    最佳答案

    由于您提到的原因,Chrome 98 及更早版本无法在后台服务人员中执行此操作。
    还有一个bug这阻止了在正常可见的 chrome-extension:// 中执行此操作页面或 iframe。它已在 Chrome 91 中修复。
    解决方案
    使用fetch在 Chrome 99 and newer .
    在旧版本中,使用以下解决方法。
    解决方法 1:文件系统 API,Chrome 86+
    ManifestV3 扩展可以使用新的 File System API读取文件的内容,例如在通过 web_accessible_resources 暴露的 iframe 中.
    解决方法 2. 扩展框架,Chrome 91+
    使用在该 pdf 选项卡中运行的内容脚本:

  • matches manifest.json 中应包含 <all_urls>file://*/*并且文件访问应该由用户启用
    您的扩展程序的 chrome://extensions UI。或者,您可以使用activeTab许可和 programmatic injection当用户
    单击扩展程序的图标或通过上下文菜单调用它。
  • 内容脚本添加了一个指向 iframe.html 的不可见 iframe web_accessible_resources 中公开的文件
  • iframe.html加载 iframe.js它像往常一样使用 XMLHttpRequest 。由于 iframe 有 chrome-extension:// URL 其环境
    与您的旧后台脚本相同,因此您可以做任何事情
    你以前在那里做过。

  • 解决方法 3. 扩展窗口/标签,Chrome 91+
    另一种解决方案是使用您的任何其他可见页面
    action 这样的扩展名弹出或选项页面或任何其他
    chrome-extension://属于您的扩展程序的页面,因为它们可以
    访问 file://通过 XMLHttpRequest 的 URL 与以前相同。
    笔记
  • 文件访问应在 chrome://extensions 中启用此扩展程序的页面。
  • 关于google-chrome-extension - Chrome 扩展 - 如何访问本地文件 ://with manifest v3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66245298/

    相关文章:

    javascript - 在警报中返回用户输入的简单 Chrome 扩展

    javascript - 是否可以动态更改 manifest.json 文件

    json - 如何在 chrome 扩展 manifest.json 文件中设置多个内容安全策略

    google-chrome - 未检测到子目录中 Web 应用程序的 manifest.json

    javascript - 注入(inject)的 CSS 未在 Chrome 扩展中加载

    google-chrome-extension - chrome 扩展 websocket 保持事件状态

    javascript - 从 chrome 扩展读取页面的链接脚本

    node.js - MS Teams bot deploy 使用消息 "Manifest parsing has failed"拒绝自动生成的 manifest.json

    google-chrome-extension - 消息传递不起作用

    javascript - 如何仅在 JavaScript 中使用 URLs Tabs 数组将 HTML 页面呈现为 PNG/JPEG 图像?