Chrome扩展程序 - 如何在manifest v3中访问本地文件://

5
我有一个Chrome扩展程序,可以(如果您允许访问文件URL)抓取您在Chrome中打开的本地pdf文件,并将其发送到我们的API进行处理。这是通过从后台脚本使用XMLHttpRequest来获取PDF文件file:///Users/user/whatever/testfile.pdf完成的。
当迁移到Chrome扩展程序的manifest v3时,后台脚本变成了服务工作者。在服务工作者中,只有fetch可用,而没有XMLHttpRequest。问题是,fetch仅支持http和https,不支持file:// URL。那么我该如何实现与Chrome扩展程序相同的功能,即获取本地文件?
编辑:我还尝试过以下操作:
  1. 按照答案建议从注入的iframe中发出XMLHttpRequest请求。 这会在发出请求时产生错误net:ERR_UNKNOWN_URL_SCHEMEnet:ERR_UNKNOWN_URL_SCHEME

  2. 从注入的内容脚本中发出XMLHttpRequest请求。 这将会产生错误访问 'file:///.../testfile1.docx.pdf' 被CORS策略阻止,源为 'null' 的跨域请求仅支持以下协议方案: 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扩展程序后台脚本曾经是一个例外。在我的看来,从内容脚本或操作弹出窗口中访问它似乎从未被允许。
以下是参考我的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": []
  }]
}

内容脚本是通过编程方式注入的(使用webextension-polyfill支持Promise)。
browser.action.onClicked.addListener(async (tab: Tab) => {
  await browser.scripting.executeScript({files: [ "inject.js" ], target: {tabId: tab.id}});
});
1个回答

5

由于您提到的原因,Chrome 98及更早版本不能在后台服务工作程序中完成该操作。

还存在一个错误,它阻止了在正常可见的chrome-extension://页面或iframe中执行该操作。在Chrome 91中已经修复了这个问题。

解决方法

在Chrome 99及以上版本中使用fetch
在旧版本中,请使用以下解决方法。

解决方法1:文件系统API,Chrome 86+

ManifestV3扩展可以使用新的文件系统API来读取文件的内容,例如在通过web_accessible_resources公开的iframe内部。

解决方法2:扩展框架,Chrome 91+

在包含pdf的选项卡中使用内容脚本:

  1. manifest.json中的matches应包含<all_urls>file://*/*,并且文件访问权限应在chrome://extensions UI中为您的扩展启用。或者,当用户单击您的扩展程序图标或通过上下文菜单调用时,您可以使用activeTab权限和编程注入
  2. 内容脚本添加一个指向在web_accessible_resources中公开了iframe.html文件的不可见iframe。
  3. iframe.html加载iframe.js,像往常一样使用XMLHttpRequest。由于iframe具有chrome-extension:// URL,因此其环境与旧的背景脚本相同,因此您可以在这里完成以前所做的所有操作。

解决方法3:扩展窗口/选项卡,Chrome 91+

另一种解决方法是使用扩展的任何其他可见页面,例如action弹出窗口或选项页或属于扩展的任何其他chrome-extension://页面,它们可以通过XMLHttpRequest访问file:// URL,与以前一样。

注意事项

  • 对于该扩展,文件访问权限应在chrome://extensions页面中启用。

抱歉,这些方法都没有奏效,请看我对问题所做的编辑。 - Clara Attermo
是的,谢谢你帮忙通过了。 - Clara Attermo
自Chrome 99起,fetch支持file://协议。 - wOxxOm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接