Спасибо за это предложение. Если у вас есть шанс, не могли бы вы взглянуть на мою попытку использовать ее и мои вопросы, написанные внизу первоначального вопроса? У меня есть часть этого, но концептуально я не понимаю некоторые необходимые шаги. Спасибо.

о File API и желая записывать данные непосредственно из базы данных indexedDB на клиентский диск вместо того, чтобы сначала собирать и хранить большой двоичный объект в оперативной памяти для загрузки на диск, есть несколько основных моментов, которые я не понимаю.

В документах MDN встречаются эти два утверждения:

В Gecko привилегированный код может создавать объекты File, представляющие любой локальный файл, без взаимодействия с пользователем.

Если вы хотите использовать DOM File API в коде Chrome, вы можете сделать это без ограничений. Фактически вы получаете одну бонусную особенность: вы можете создавать объекты File, указывая путь к файлу на компьютере пользователя. Это работает только из привилегированного кода, поэтому веб-контент не может этого сделать.

Где именно можно написать Chrome-код и / или код Gecko? Это за пределами веб-расширения? Я читал и экспериментировал с расширениями; поэтому я не спрашиваю конкретно о том, как получить к ним доступ.

Меня не волнует нормальная веб-страница и сервер, обращающийся к клиентскому диску. Я знаю, что не разрешено защищать человека.

Меня интересует, что можно сделать в автономном режиме через браузер - с помощью веб-расширений и / или отдельного профиля, предоставляющего специальные разрешения, но без node.js, электрона и т. Д. - человеком, который сознательно хочет использовать браузер может сделать то, что они должны были встроить в ОС, а не браузер.

Иными словами, если я хочу использовать браузер просто для запуска своего кода JavaScript для выполнения задач в автономном режиме на моем собственном компьютере, где написан привилегированный код, который предоставляет доступ к этим типам API, которые не подвержены проблемам безопасности нормальной веб-страницы?

Это все еще javascript или C ++ в этих областях?

Спасибо.

Этот старый вопрос предоставляет ссылку на ихрасширение который включает в себя File API, который записывает на диск способом, который, по-видимому, предоставляет средство для обхода создания большого блока данных. Ей шесть лет, но, похоже, она содержит то, что нужно, по крайней мере, для начала.

Я не имею в виду их попытки обойти использование indexedDB, но просто использование этого типа расширения может позволить записывать каждый объект из базы данных непосредственно на клиентский диск без необходимости сначала создавать большой двоичный объект для загрузки.

Попытка использовать предложение Эндрю Свона

Я пытаюсь собрать все воедино, но дошел до того, что не уверен, как продолжить. Я написал код ниже в фоновом скрипте расширения. При попытке использовать предложение Эндрю Свона планируется запустить запрос GET для текстового / CSV-файла, который перехватывается и заменяется данными, извлеченными из базы данных и записанными в запрос GET потоковым фильтром.

Сначала сделайте запрос GET к фиктивному URL и прослушайте ответ следующим образом:

 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();

   };

 }

Сообщение, отправленное из фонового скрипта в функцию request.onreadystatechange, получено в скрипте содержимого, а request.status имеет значение «0».

Фильтр filter.onstart используется, потому что событие ondata никогда не сработает, поскольку URL-адрес является поддельным. Кроме того, это означает, что не будет конвертации данных из URL, а будет только запись новых данных через фильтр.

Данные str записываются и принимаются запросом, но только как responseText, а не как заголовок ответа. В request.status остается «0» вместо «200».

Кажется, что нельзя изменить заголовок ответа, если только в onHeadersReceived, который, как представляется, никогда не будет иметь место, для поддельной ссылки. Тем не менее, я попробовал это на реальном URL-адресе, и, хотя событие сработало, ошибка webRequest.HttpHeaders не была выдана функция. У меня были «responseHeaders» в webRequest extraInfoSpec в то время.

Мои вопросы:

Можно ли записать заголовок ответа, чтобы установить для request.status значение «200», а затем начать запись данных базы данных с помощью асинхронной функции в небольших блоках по мере извлечения?

Может ли раздел «Расположение содержимого» в ответе заголовка быть установлен таким образом, чтобы он автоматически запускал загрузку response.text и позволял пользователю выбирать имя файла и место сохранения, оставаясь «открытым», так как продолжайте запись в файл в качестве данных извлекается из базы данных и передается в запрос GET через filter.write ()?

Спасибо.

Заключение

Это была хорошая идея, но я не думаю, что это возможно по крайней мере по двум причинам.

Одна из них заключается в том, что webRequest вообще не перехватывает функцию downloads.download () или любое событие загрузки; таким образом, вы не можете перехватить загрузку, и необходимо событие с расположением содержимого «вложение», чтобы даже попытаться записать в него поток. Я мог перехватить принудительный щелчок на теге привязки href, но никакие другие события не сработали, кроме onBeforeRequest.

Другое - то, что заголовок ответа не может быть изменен до события onHeadersReceived, что означает, что поддельный URL должен что-то возвращать. Вы не можете просто отменить это в onBeforeRequest. Таким образом, это не будет работать в автономном режиме. Но, даже если вы разрешите ему обрабатывать в Интернете существующий URL-адрес, который возвращает заголовок ответа, он не примет изменения. Я неоднократно пытался изменить заголовок ответа, и он просто не будет работать. Я попытался получить XMLHttpRequest GET и может перехватывать события, которые запускаются, но не может изменить заголовок ответа; поэтому нельзя установить Content Disposition на «вложение», с файлом или без него, чтобы начать загрузку. Я могу написать в него, но это бесполезно, если он не собирается загружать то, что написано. Было бы хорошо, если бы письменный контент шел на веб-страницу.

Кроме того, если вы перенаправите URL-адрес по пути к чему-либо, кроме приемлемого URL-адреса webRequest, другие события не будут перехватываться. Таким образом, если перенаправить на URL объекта в onBeforeRequest, вы не перехватите этап заголовков ответов в webRequest, но сможете просмотреть threm в событии onreadystatechange XMLHttpRequest.

Таким образом, в результате получается, что заголовки ответа не могут быть изменены, даже несмотря на то, что в MDN Web Docs говорится, что это возможно. И эта идея использования потокового фильтра awebRequest для потоковой передачи данных, сгенерированных на клиенте или извлеченных из базы данных indexedDB, в отличие от создания одного большого двоичного объекта для загрузки, не будет работать, поскольку не может перехватить загрузку или изменить заголовки ответа на вызвать загрузку, в которую можно записать через фильтр потока.

Это была интересная идея. Я все еще задаюсь вопросом, останется ли загрузка, так сказать, «открытой», пока данные записываются на клиенте и передаются блоками или кусками. Возможно, если бы эта часть заголовков ответа, в которой указано, как данные должны быть переданы и получены, была изменена, это также сработало бы.

На данный момент я больше не преследую этот подход. В одном из веб-документов или записей об ошибках указано, что планируется разрешить перехват URL-адреса данных. Возможно, для автономной загрузки клиенту это предпочтительнее, чем фальшивый URL.

Если кто-то заставит это работать, пожалуйста, дайте нам знать. Спасибо.

Ответы на вопрос(1)

Ваш ответ на вопрос