Javascript 在 Google Chrome 中指定 Blob 编码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6672834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Specifying blob encoding in Google Chrome
提问by Eli Grey
The following code (vendor normalized) works perfectly fine and displays "??? Test" in Firefox 8, but displays "a?a?a?? Test" in Google Chrome. Is there any way to preserve encoding of blobs in Google Chrome short of writing a file to a temporary filesystem using the filesystem API?
以下代码(供应商标准化)运行良好,在 Firefox 8 中显示“??? Test”,但在 Google Chrome 中显示“a?a?a?? Test”。除了使用文件系统 API 将文件写入临时文件系统之外,是否有任何方法可以在 Google Chrome 中保留 blob 的编码?
var b = new Blob(["??? Test"], {type: "text/plain;charset=UTF-8"});
var url = URL.createObjectURL(b);
open(url);
回答by panzi
Gecko (Firefox), WebKit (Safari, Chrome) and Opera support the non-standard btoa
function for encoding a string in base 64. In order to get a base 64 string containing a string encoded as UTF-8 you need to use the encodeURIComponent
-unescape
trick. encodeURIComponent
encodes a string as UTF-8 URL but unescape
decodes each %xx
as a single character. btoa
expects a binary string of whatever encoding you want.
Gecko (Firefox)、WebKit (Safari、Chrome) 和 Opera 支持使用btoa
base 64 编码字符串的非标准函数。为了获得包含编码为 UTF-8 的字符串的 base 64 字符串,您需要使用encodeURIComponent
-unescape
技巧. 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");
Of course this does not work in IE, but I think IE 10 will support the Blob
-API. Who knows how it will handle encodings.
当然这在 IE 中不起作用,但我认为 IE 10 将支持Blob
-API。谁知道它将如何处理编码。
PS: IE seems not to be able to window.open
data:-urls and would have a ridiculous small url length limitation anyway.
PS:IE 似乎无法window.open
data:-urls 并且无论如何都会有一个荒谬的小 url 长度限制。
PPS: This works for me in Chrome:
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","");
回答by Matthew
The problem is the default page encoding for new tabs in Chrome. When the new window opens (after window.open(url)
) choose View > Encoding > Unicode from the Chrome menu. This changed the displayed text from "a?a?a?? Test" to "??? Test" for me in Chrome 13.
问题是 Chrome 中新标签页的默认页面编码。当新窗口打开时(在 之后window.open(url)
),从 Chrome 菜单中选择查看 > 编码 > Unicode。这将 Chrome 13 中显示的文本从“a?a?a?? Test”更改为“??? Test”。
If you want a solution that will let you open blobs in new windows regardless of the default encoding, then you can rely on the fact that a document in an iframe will inherit the parent document encoding when it doesn't explicitly specify its own encoding. So you can open a window with a blank HTML document served with a Content-Type:text/html; charset=utf-8
header, then append an iframe to the body with the src
attribute set to the blob URL.
如果您想要一个无论默认编码如何都可以让您在新窗口中打开 blob 的解决方案,那么您可以依赖这样一个事实,即 iframe 中的文档在未明确指定自己的编码时将继承父文档编码。因此,您可以打开一个带有Content-Type:text/html; charset=utf-8
标题的空白 HTML 文档的窗口,然后将 iframe 附加到正文中,并将src
属性设置为 blob URL。
回答by Kaiido
new Blob(["??? Test"])
will generate a Blob representing that text encoded as UTF-8.
new Blob(["??? Test"])
将生成一个表示该文本编码为 UTF-8 的 Blob。
That browsers assumes text files should be read in ISO is a weird choice IMM.
浏览器假定应该在 ISO 中读取文本文件是一个奇怪的选择 IMM。
Appending the { type: "text/plain;charset=utf8" }
should generate the proper Content-Type
header when they browsers will serve it through a blob URI. That Chrome doesn't with open()
sounds like a bug.
当浏览器通过 blob URI 提供服务时,附加{ type: "text/plain;charset=utf8" }
应该会生成正确的Content-Type
标头。Chrome 没有open()
听起来像一个错误。
Now you can workaround this by prepending a BOM sequence at the beginning of your text file, so that Chrome detects it as UTF, even without Content-Typeinfo:
现在,您可以通过在文本文件的开头添加 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);
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 )] ) );
})();
<a class="BOM">open file with BOM</a><br>
<a class="no-BOM">open file without BOM</a>