【问题标题】:pass input file to background script将输入文件传递给后台脚本
【发布时间】:2014-06-12 20:43:24
【问题描述】:

我想将输入文件从内容页面传递到扩展后台脚本,然后在扩展后台脚本中使用 FileReader() 加载它。

所以在网页中我有一个<input type="file"> 并且从 onchange 事件中我将文件从内容脚本传递到后台页面,如下所示:

 var myfile = document.getElementById('fileid').files[0];
 chrome.runtime.sendMessage({myevent: "start", inputfile: myfile}, function(response) {});

在后台脚本中我有这个:

chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){

   if(message.myevent==="start")
   {
      var reader = new FileReader();

         reader.onload = function(e) {
              // file is loaded 
         }  


       reader.readAsArrayBuffer(message.inputfile);
   }
});

但是 FileReader 没有加载它,我不确定这是否正确,但我需要的只是将输入文件元素传递给后台脚本并使用 FileReader 加载它以使用来自后台脚本的 HTTP POST 发送它。请告诉我出了什么问题或如何正确地做。如果我看到示例代码将有很大帮助,因为我是 chrome 扩展开发的新手,而且经验不足。

【问题讨论】:

    标签: javascript jquery html google-chrome google-chrome-extension


    【解决方案1】:

    通过 Chrome 扩展消息 API 发送的所有消息都必须是 JSON 可序列化的。 如果你想在后台页面获取文件的内容,你最好为File对象创建一个(临时)URL,将此URL传递给后台页面并使用XMLHttpRequest获取其内容:

    // Create URL
    var url = URL.createObjectURL(myfile);
    // Pass URL to background page (ommited for brevity) and load it..
    var x = new XMLHttpRequest();
    x.onload = function() {
         var result = x.response;
         // TODO: Use [object ArrayBuffer]
    };
    x.open('GET', url); // <-- blob:-url created in content script
    x.responseType = 'arraybuffer';
    x.send();
    

    虽然你为什么要将文件发送到后台页面?内容脚本也可以发送跨域请求。

    【讨论】:

    • 这很有意义,我会检查并回复你,我赞成你的答案,因为它看起来不错,对我来说是新事物,我很高兴看到你的解决方案适用我,我会接受的。谢谢
    • 我已接受您的回答。如果文件的大小很小,则可以正常工作,但如果文件大小为 200 Mb,则扩展名将崩溃。我尝试做的是创建多部分 HTTP POST 并上传一个大文件。你对此有什么建议吗?
    • @Jigberto 崩溃听起来像一个错误。您能否提供带有最小示例的源代码并在crbug.com/new 提供重现步骤?如果需要,我也可以为您报告错误。
    • 感谢您的支持,我已经为此打开了一个单独的问题,请检查链接,希望您能帮助我。谢谢。 stackoverflow.com/questions/24211073/…
    • @Armand 在 Chrome 中,仍然没有一种简单/方便的方式将文件发送到后台。由于已经编写了答案,Web 可访问的扩展框架可以访问与背景页面相同类型的 API,因此可以将这些 API 与 DOM 的 postMessage 一起使用来发送文件。然而这更复杂...... Firefox 确实在其扩展消息 API 中支持structured cloning,它允许您直接将文件/Blob 发送到后台,这使得它更容易。
    【解决方案2】:

    这适用于 chrome。你可以在这里找到完整的生产代码。

    https://github.com/Leslie-Wong-H/BoostPic/tree/7513b3b8d67fc6f57718dc8b9ff1d5646ad03c75/BoostPic_Chrome/js

    main.js:

    
        // Crossbrowser support for URL
        const URLObj = window.URL || webkitURL;
    
        // Creates a DOMString containing a URL representing the object given in the parameter
        // namely the original Blob
        const blobUrl = URLObj.createObjectURL(imageBlob);
        console.log(blobUrl);
        chrome.runtime.sendMessage(blobUrl, (res) => {
          imgUrl = res;
          console.log(imgUrl);
          clearInterval(refreshIntervalId);
          // To prevent that it happens to halt at "  Image uploading ..."
          setTimeout(() => {
            var imgUrlText = document.querySelector(imgUrlTextBoxId);
            imgUrlText.value = imgUrl;
          }, 1000);
          // double check to clear interval to prevent infinite error loop of LoadingStateOne
          // Hope it works.
          setTimeout(() => {
            clearInterval(refreshIntervalId);
          }, 500);
          console.log("Stop uploading state message");
    

    background.js:

    
    chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
      if (request.startsWith("blob")) {
        console.log("RECEIVED");
        getBase64Url(request).then((res) => {
          console.log("Arrived here");
          // Acquired from https://stackoverflow.com/questions/18650168/convert-blob-to-base64/18650249#
          const reader = new FileReader();
          reader.readAsDataURL(res);
          reader.onloadend = function () {
            const base64data = reader.result;
            console.log(base64data);
    

    【讨论】:

      猜你喜欢
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-05
      • 2021-12-10
      • 2015-04-17
      • 1970-01-01
      相关资源
      最近更新 更多