【问题标题】:Downloading mp3 files using html5 blobs in a chrome-extension在 chrome 扩展中使用 html5 blob 下载 mp3 文件
【发布时间】:2011-09-04 03:34:24
【问题描述】:

我正在尝试创建一个可以下载 mp3 文件的 google-chrome-extension。我正在尝试使用 HTML5 blob 和 iframe 来触发下载,但它似乎不起作用。这是我的代码:

var finalURL = "server1.example.com/u25561664/audio/120774.mp3";

var xhr = new XMLHttpRequest();
    xhr.open("GET", finalURL, true);
    xhr.setRequestHeader('Content-Type', 'application/octet-stream');
    xhr.onreadystatechange = function() 
    {
        if(xhr.readyState == 4 && xhr.status == 200) 
        {   
            var bb = new (window.BlobBuilder || window.WebKitBlobBuilder)();
            bb.append(xhr.responseText);
            var blob = bb.getBlob("application/octet-stream");

            var saveas = document.createElement("iframe");
            saveas.style.display = "none";

            saveas.src = window.webkitURL.createObjectURL(blob); 

            document.body.appendChild(saveas);

            delete xhr;
            delete blob;
            delete bb;
        }
    }
 xhr.send();

在控制台中查看时,blob 已正确创建,设置看起来正确:

尺寸:15312172 类型:“应用程序/八位字节流”

但是,当我尝试由createObjectURL() 创建的链接时,

blob:chrome-extension://dkhkkcnjlmfnnmaobedahgcljonancbe/b6c2e829-c811-4239-bd06-8506a67cab04

我得到一个空白文档和一个警告说

资源解释为文档但 以 MIME 类型传输 应用程序/八位字节流。

如何让我的代码正确下载文件?

【问题讨论】:

  • 我面临着类似的情况。我正在使用铬。对我来说,xhr.status 返回 0。这是否意味着 XMLHttpRequest 不支持跨域脚本?有其他选择吗?
  • XMLHttpRequests 必须遵循跨域策略。如果您想从另一个域调用页面,则需要在扩展的清单文件中添加该域。

标签: javascript html google-chrome-extension blob


【解决方案1】:

我不确定,但我认为这是您服务器的问题。我刚刚尝试了您的一段代码来下载一些 mp3 文件的示例 blob,一切正常。所以也许:

  1. 您的服务器上不存在此文件
  2. 您的服务器为 mp3 文件输出了错误的 mime 类型

【讨论】:

  • 我检查了文件存在于服务器上,我很确定 MIME 类型是正确的。如何检查服务器输出的 mime 类型?
  • 最简单的方法是获取“Content-type”响应头:xhr.getResponseHeader('Content-type');
  • 我正在返回“音频/mpeg”。你不能为此使用八位字节流吗?将 getBlob 切换为使用“audio/mpeg”也会出现同样的问题。
【解决方案2】:

以下代码在 Google chrome 14.0.835.163 中为我工作:

var finalURL = "http://localhost/Music/123a4.mp3";
var xhr = new XMLHttpRequest();
xhr.overrideMimeType("application/octet-stream");
//xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
xhr.open("GET", finalURL, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() {
      var bb = new (window.BlobBuilder || window.WebKitBlobBuilder)();
      var res = xhr.response;
      if (res){
          var byteArray = new Uint8Array(res);
      }
      bb.append(byteArray.buffer);
      var blob = bb.getBlob("application/octet-stream");
      var iframe = document.createElement("iframe");
      iframe.style.display = "none";
      iframe.src = window.webkitURL.createObjectURL(blob);
      document.body.appendChild(iframe);
};
xhr.send(null);

【讨论】:

  • @Xan 任何带有 Blobs 的浏览器都有 XHR2,所以这样做 onreadystatechange 充其量是多余的(你可以只使用 onload),在 GC 环境中使用 delete 简直是愚蠢的,并且会在这种情况下什么都不做(特别是,你不能 delete 你用 var 定义的东西是无操作的)。我只是改变了这两件事——这个答案可以进一步改进,但我不想改变它的含义——只是更小的语法问题。
猜你喜欢
  • 1970-01-01
  • 2020-05-16
  • 2011-12-24
  • 2011-06-18
  • 1970-01-01
  • 2012-12-20
  • 1970-01-01
相关资源
最近更新 更多