什么是特权代码,chrome 代码,Gecko?

What and where exactly are privileged code, chrome code, Gecko?

阅读文件 API 并希望将数据直接从 indexedDB 数据库写入客户端磁盘,而不是首先在 RAM 中构建并保存一个大 blob 以下载到磁盘,有一些基本的我不明白的项目。

在 MDN 文档中找到这两个语句:

In Gecko, privileged code can create File objects representing any local file without user interaction.

If you want to use the DOM File API in chrome code, you can do so without restriction. In fact, you get one bonus feature: you can create File objects specifying the path of the file on the user's computer. This only works from privileged code, so web content can't do it.

  1. chrome 代码 and/or Gecko 特权代码到底写在哪里?这超出了网络扩展吗?我已经阅读并尝试了扩展;所以,我并没有具体询问如何访问它们。

我不关心 'normal' 网页和服务器访问客户端磁盘。我知道为了保护个人是不允许的。

我对可以通过浏览器离线完成的事情很感兴趣——借助网络扩展 and/or 一个单独的配置文件授予特殊权限但没有 node.js、electron 等- - 一个人故意使用浏览器来做他们应该在 OS 而不是浏览器中做的事情。

  1. 换句话说,如果我只想使用浏览器 运行 我的 javascript 代码在我自己的机器上全部离线执行任务,特权代码在哪里允许访问不受普通网页安全问题影响的这些类型的 API?

  2. 这些方面还是javascript还是C++?

谢谢。

This old question provides a link to their extension 其中包括文件 API,它以一种似乎提供绕过大数据块创建的方式写入磁盘。它已有 6 年历史,但似乎包含了所需的内容,至少是入门所需的内容。

我不是指他们试图绕过使用 indexedDB,而是说使用这种类型的扩展可以允许将每个 object 从数据库直接写入客户端磁盘,而无需先生成要下载的大 blob。

尝试采纳 Andrew Swan 的建议

我正在尝试将各个部分拼凑起来,但已经到了我不确定如何继续的地步。我在扩展的后台脚本中写了下面的代码。在尝试采用 Andrew Swan 的建议时,计划是发起对 text/csv 文件的 GET 请求,该文件被拦截并替换为从数据库中提取的数据并由流过滤器写入 GET 请求。

首先,向伪造的url发出GET请求并监听响应,如下:

 let request = new XMLHttpRequest();

 request.open("GET", url );

 request.setRequestHeader( "Content-Type", "text/csv" );

 request.send(null);

 request.onreadystatechange = () =>

  {

   portFromCS.postMessage( { 'func' : 'disp_result', 'args' : { 'msg' : "request.status :", 'value' : request.status + ' : ' + request.statusText} } );

  };

二、拦截请求写入GET,如下:

 browser.webRequest.onBeforeRequest.addListener(

  listener,

  { urls : ["<all_urls>"] },

 ["blocking"] );


 function listener( details ) 

 { 

   let filter = browser.webRequest.filterResponseData(details.requestId);
   let decoder = new TextDecoder("utf-8");
   let encoder = new TextEncoder();

   filter.onstart = event =>

    {

      let str = decoder.decode(event.data, {stream: true});

      str = '' +
      'HTTP/1.1 200 OK \r\n' +
      'Content-Length: 17 \r\n' +
      'Content-Type: text/csv \r\n\r\n\r\n' +
      'This is a string.';


      filter.write(encoder.encode(str));

      filter.disconnect();

   };

 }

content脚本接收到request.onreadystatechange函数后台脚本发送的消息,request.status为'0'

使用 filter.onstart 是因为 ondata 事件永远不会触发,因为 url 是伪造的。此外,这意味着不会对来自 url 的数据进行转换,而只会通过过滤器写入新数据。

str 数据由请求写入和接收,但仅作为 responseText 而不是响应 header。 request.status 保持为“0”而不是“200”。

似乎无法更改响应 header 除非在 onHeadersReceived 中,它似乎永远不会发生,因为是伪造的 url。但是,我在真实的 url 上进行了尝试,即使触发了事件,也抛出了 webRequest.HttpHeaders 不是函数的错误。当时我在 webRequest extraInfoSpec 中有 "responseHeaders"。

我的问题是:

  1. 是否可以写入响应 header 以将 request.status 设置为“200”,然后开始通过异步函数在检索到的小块中写入数据库数据?

  2. 是否可以设置 header 响应的内容配置部分,使其自动开始 response.text 下载并允许用户 select文件名和保存位置,并在数据从数据库中提取并通过 filter.write()?

    [= 传递给 GET 请求时保持 "open" 继续写入文件85=]

谢谢。

结论

这是个好主意,但至少出于两个原因,我认为这是不可能的。

一个是 webRequest 似乎根本没有拦截 downloads.download() 函数或任何下载事件;因此,您无法拦截下载,甚至需要一个内容处置为 'attachment' 的事件才能尝试使用流写入它。我可以拦截对锚标记 href 的强制点击,但除了 onBeforeRequest 之外没有触发其他事件。

另一个是在 onHeadersReceived 事件之前无法修改响应 header,这意味着假 URL 必须 return 某些东西。你不能只在 onBeforeRequest 中取消它。所以,这不会脱机工作。但是,即使您让它联机处理现有的 URL,return 是一个响应 header,它也不会接受修改。我反复尝试修改响应header 它就是行不通。我尝试了 XMLHttpRequest GET 并可以拦截触发但无法修改响应的事件 header;因此,无论有无文件,都无法将 Content Disposition 设置为 'attachment' 来开始下载。我可以写信给它,但除非它要下载所写的内容,否则这没什么用。写的内容要是上网页就好了

此外,如果您将 URL 沿途重定向到 webRequest 可接受的 URL 以外的任何其他事件,则其他事件将无法拦截。因此,如果重定向到 onBeforeRequest 中的 object URL,则不会拦截 webRequest 中的响应 headers 阶段,但可以在 XMLHttpRequest 的 onreadystatechange 事件中查看 threm。

因此,结果是响应 headers 似乎无法修改,即使 MDN Web 文档说这是可能的。而且,这种使用 webRequest 流过滤器来流式传输在客户端生成的数据或从 indexedDB 数据库中提取的数据,而不是构建一个大的 blob 以供下载的想法是行不通的,因为无法拦截下载或更改响应 headers 触发通过流过滤器写入的下载。

虽然这是一个有趣的想法。我仍然想知道下载是否会保持 'open',可以这么说,而数据正在客户端上写入并以块或块的形式传递。也许,如果响应的那部分 headers 说明了如何传递和接收数据,那么它也可以工作。

目前,我不再追求这种方法。其中一个 Web Docs 或一个错误记录表明它计划允许数据 URL 被拦截。也许,对于客户端的离线下载,这比假的 URL.

更可取

如果有人成功了,请告诉我们。谢谢。

几个术语:

  • "Gecko" 是构建 Firefox(以及 Thunderbird 等其他一些应用程序)的渲染引擎
  • "Chrome" 在此上下文中表示浏览器用户界面和功能,而不是浏览器显示的网页内容。

在 Firefox 中,大部分浏览器 chrome 都是在 Javascript 中实现的。实现用户界面的代码需要能够做普通网页不能做的事情(比如读写本地文件系统)。因此,此代码 运行 与作为网页一部分的 Javascript 具有不同的权限。术语 "privileged code"、"chrome privileged code"、"Gecko privileged code" 都是描述同一事物的不同方式:Javascript 内置于浏览器并可以访问网页功能的代码没有。

在 Firefox Quantum(版本 57)发布之前,允许 Firefox 扩展 运行 特权 Javascript 代码。正如您所想象的那样,这充满了安全性、性能和稳定性等方面的问题。使用 WebExtensions,扩展现在 运行 具有与常规 Web 内容相同级别的权限(即,它们不以提升的权限执行)。某些浏览器功能通过 extension APIs.

公开给扩展

因此,如果您对扩展的功能感兴趣,那么 MDN 上任何引用特权代码的文档实际上都是无关紧要的。当前没有任何可用于 WebExtensions 的 API 允许您直接访问文件系统,但是有一个 open bug 来添加一些这种功能。 (这个bug已经存在了一段时间了,不过估计很快就会有进展了...)