javascript - 下载生成的二进制内容在磁盘文件中包含 utf-8 编码的字符

标签 javascript utf-8 google-chrome-extension

我正在尝试使用以下代码将生成的 zip 文件从 chrome 扩展程序保存到磁盘:

function sendFile (nm, file) {
  var a = document.createElement('a');
  a.href = window.URL.createObjectURL(file);
  a.download = nm; // file name
  a.style.display = 'none';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}
function downloadZip (nm) {
  window.URL = window.webkitURL || window.URL;
  var content;
  content = zip.generate();
  var file = new Blob ([content], {type:'application/base64'});
  sendFile ("x.b64", file);
  content = zip.generate({base64:false});
  var file = new Blob ([content], {type:'application/binary'});
  sendFile ("x.zip", file);
}

目前,这将我的 zip 内容保存为两个版本,第一个版本是 base64 编码的,当我使用 base64 -d 对其进行解码时,生成的 zip 就可以了。
第二个版本应该只保存原始数据(zip 文件),但该原始数据以 utf-8 编码到达我的磁盘上。 (每个 >= 0x80 的值都以 0xc2 开头)。那么如何摆脱这个utf-8编码呢?尝试了各种类型字符串,例如 application/zip,或者完全省略类型信息,它总是以 utf-8 编码到达。我也很好奇如何让浏览器自行存储/转换 base64 数据(第一种情况),以便它们作为解码的二进制数据到达我的磁盘上...我使用的是 Chrome 版本 23.0.1271.95 m

PS:我使用浏览器内的 hexdump 实用程序分析的第二个内容:它不包含 utf-8 编码(或者我的 hexdump 调用了进行隐式转换的内容)。为了完整起见(抱歉,它只是从 c 转来的,所以它可能不是那么酷的 js 代码),我将其附加在这里:

function hex (bytes, val) {
  var ret="";
  var tmp="";
  for (var i=0;i<bytes;i++) {
    tmp=val.toString (16);
    if (tmp.length<2)
      tmp="0"+tmp;
    ret=tmp+ret;
    val>>=8;
  }
  return ret;
}
function hexdump (buf, len) {
  var p=0;
  while (p<len) {
    line=hex (2,p);
    var i;
    for (i=0;i<16;i++) {
      if (i==8)
        line +=" ";
      if (p+i<len)
        line+=" "+hex(1,buf.charCodeAt(p+i));
      else
        line+="   ";
    }
    line+=" |";
    for (i=0;i<16;i++) {
      if (p+i<len) {
        var cc=buf.charCodeAt (p+i);
        line+= ((cc>=32)&&(cc<=127)&&(cc!='|')?String.fromCharCode(cc):'.');
      }
    }
    p+=16;
    console.log (line);
  }
}

最佳答案

来自working draft :

If element is a DOMString, run the following substeps:

  • Let s be the result of converting element to a sequence of Unicode characters [Unicode] using the algorithm for doing so in WebIDL [WebIDL].

  • Encode s as UTF-8 and append the resulting bytes to bytes.

因此字符串总是转换为 UTF-8,并且没有参数可以影响这一点。这不会影响 Base64 字符串,因为它们仅包含与每个代码点匹配单个字节的字符,并且代码点和字节具有相同的值。幸运的是,Blob 公开了较低级别的接口(interface)(直接字节),因此该限制并不重要。

你可以这样做:

var binaryString = zip.generate({base64: false}), //By glancing over the source I trust the string is in "binary" form
    len = binaryString.length,    //I.E. having only code points 0 - 255 that represent bytes
    bytes = new Uint8Array(len);

for( var i = 0; i < len; ++i ) {
    bytes[i] = binaryString.charCodeAt(i);
}

var file = new Blob([bytes], {type:'application/zip'});
sendFile( "myzip.zip", file );

关于javascript - 下载生成的二进制内容在磁盘文件中包含 utf-8 编码的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13790949/

相关文章:

javascript - 带控件的视频元素停止传播触摸事件

javascript - 通过拖动选择表格中的单元格

javascript - 为什么我的类构造函数中出现 "Uncaught ReferenceError: this is not defined"?

google-chrome-extension - 如何在 linux headless (headless)服务器上预安装 chrome 扩展

javascript - 使用 Javascript 动态更改 View

javascript - 从 javascript 在浏览器 (Chrome) 中播放声音

javascript - Webix 数据布局中的分层数据集

c# - 通过使用准备语句在 C# 中查询 Utf-8

swift - 无法在 swift 中将字符串编码为 utf8,将 utf8 编码为 base64

php - 在 php 和 javascript 之间传递 utf-8 字符串