在Google Chrome中指定blob编码

Eli*_*rey 11 javascript encoding google-chrome fileapi

以下代码(供应商规范化)工作得很好,并在Firefox 8中显示"➀➁➂测试",但在谷歌浏览器中显示"“â,â€,测试".有没有办法在使用文件系统API将文件写入临时文件系统时保留Google Chrome中的blob编码?

var bb = new BlobBuilder;
bb.append("??? Test");
var b = bb.getBlob("text/plain;charset=UTF-8");
var url = URL.createObjectURL(b);
open(url);
Run Code Online (Sandbox Code Playgroud)

pan*_*nzi 10

Gecko(Firefox),WebKit(Safari,Chrome)和Opera支持btoa在base 64中编码字符串的非标准函数.为了获得包含编码为UTF-8的字符串的base 64字符串,你需要使用encodeURIComponent- unescapetrick .encodeURIComponent将字符串编码为UTF-8 URL,但将unescape每个字符串解码%xx为单个字符.btoa期望你想要的任何编码的二进制字符串.

var base64 = btoa(unescape(encodeURIComponent(data)));
window.open("data:text/plain;charset=UTF-8;base64,"+base64,"UTF-8 Text");
Run Code Online (Sandbox Code Playgroud)

当然这在IE中不起作用,但我认为IE 10将支持Blob-API.谁知道它将如何处理编码.

PS:IE似乎无法获取window.open数据:-urls并且无论如何都会有一个荒谬的小网址长度限制.

PPS:这适用于Chrome:

var b = new Blob(["??? Test"],{encoding:"UTF-8",type:"text/plain;charset=UTF-8"});
var url = URL.createObjectURL(b);
window.open(url,"_blank","");
Run Code Online (Sandbox Code Playgroud)


Kai*_*ido 10

new Blob(["??? Test"]) 将生成一个表示该文本编码为 UTF-8 的 Blob。

浏览器假定应该在 ISO 中读取文本文件是一个奇怪的选择 IMM。

当浏览器通过 blob URI 提供服务时,附加{ type: "text/plain;charset=utf8" }应该会生成正确的Content-Type标头。Chrome 没有open()听起来像一个错误。

现在,您可以通过在文本文件的开头添加 BOM 序列来解决此问题,以便 Chrome 将其检测为 UTF,即使没有Content-Type信息:

var BOM = new Uint8Array([0xEF,0xBB,0xBF]);
var b = new Blob([ BOM, "??? Test" ]);
var url = URL.createObjectURL(b);
open(url);
Run Code Online (Sandbox Code Playgroud)

var BOM = new Uint8Array([0xEF,0xBB,0xBF]);
var b = new Blob([ BOM, "??? Test" ]);
var url = URL.createObjectURL(b);
open(url);
Run Code Online (Sandbox Code Playgroud)
var BOM = new Uint8Array([0xEF,0xBB,0xBF]);

var blob_BOM = new Blob([ BOM, "??? Test" ]);
var url_BOM = URL.createObjectURL(blob_BOM);
// for demo we also create one version without BOM
var blob_noBOM = new Blob([ "??? Test" ]);
var url_noBOM = URL.createObjectURL(blob_noBOM);

document.querySelector('.BOM').href = url_BOM;
document.querySelector('.no-BOM').href = url_noBOM;

// to check whether they contain the same data, apart from the BOM
(async() => {
  const buf_BOM = await blob_BOM.slice(3).arrayBuffer(); // remove BOM sequence
  const buf_noBOM = await blob_noBOM.arrayBuffer();
  
  console.log( 'with BOM text data:' );
  console.log( JSON.stringify( [...new Uint8Array( buf_BOM )] ) );
  console.log( 'without BOM text data:' );
  console.log( JSON.stringify( [...new Uint8Array( buf_noBOM )] ) );

})();
Run Code Online (Sandbox Code Playgroud)


Mat*_*hew 1

问题在于 Chrome 中新标签页的默认页面编码。当新窗口打开时(在 后window.open(url)),从 Chrome 菜单中选择“视图”>“编码”>“Unicode”。这将显示的文本从“\xc3\xa2\xc5\xbe\xe2\x82\xac\xc3\xa2\xc5\xbe\xc3\xa2\xc5\xbe\xe2\x80\x9a Test”更改为“\xe2\在 Chrome 13 中为我进行“x9e\x80\xe2\x9e\x81\xe2\x9e\x82 测试”。

\n\n

如果您想要一个可以让您在新窗口中打开 blob 而不管默认编码如何的解决方案,那么您可以依赖这样一个事实:iframe 中的文档在未显式指定其自己的编码时将继承父文档编码。因此,您可以打开一个带有Content-Type:text/html; charset=utf-8标题的空白 HTML 文档的窗口,然后将 iframe 附加到正文,并将src属性设置为 blob URL。

\n