根据我的测试,标题中的错误只在谷歌Chrome中抛出。我正在base64编码一个大的XML文件,以便它可以下载:
this.loader.src = "data:application/x-forcedownload;base64,"+
btoa("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+"<"+this.gamesave.tagName+">"
+this.xml.firstChild.innerHTML
+"</"+this.gamesave.tagName+">");
这一点。加载器是隐藏的iframe。
这个错误实际上是一个相当大的变化,因为通常情况下,谷歌Chrome浏览器会崩溃在btoa调用。Mozilla Firefox在这里没有问题,所以这个问题与浏览器有关。
我不知道档案里有什么奇怪的字。事实上,我相信没有非ascii字符。
问:
我如何找到有问题的字符,并替换他们,让Chrome停止抱怨?
我已经尝试使用downadify来启动下载,但它不起作用。它是不可靠的,并且不会抛出任何错误来进行调试。
我自己也遇到了这个问题。
首先,稍微修改你的代码:
var download = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+"<"+this.gamesave.tagName+">"
+this.xml.firstChild.innerHTML
+"</"+this.gamesave.tagName+">";
this.loader.src = "data:application/x-forcedownload;base64,"+
btoa(download);
然后使用你最喜欢的web检查器,在指定this.loader的代码行上放置一个断点。Src,然后执行以下代码:
for (var i = 0; i < download.length; i++) {
if (download[i].charCodeAt(0) > 255) {
console.warn('found character ' + download[i].charCodeAt(0) + ' "' + download[i] + '" at position ' + i);
}
}
根据应用程序的不同,替换超出范围的字符可能有效,也可能无效,因为您将修改数据。请参阅MDN上关于使用btoa方法使用unicode字符的说明:
https://developer.mozilla.org/en-US/docs/Web/API/window.btoa
我只是觉得我应该分享我是如何解决这个问题的,以及为什么我认为这是正确的解决方案(前提是你不针对旧浏览器进行优化)。
将数据转换为dataURL (data:…)
var blob = new Blob(
// I'm using page innerHTML as data
// note that you can use the array
// to concatenate many long strings EFFICIENTLY
[document.body.innerHTML],
// Mime type is important for data url
{type : 'text/html'}
);
// This FileReader works asynchronously, so it doesn't lag
// the web application
var a = new FileReader();
a.onload = function(e) {
// Capture result here
console.log(e.target.result);
};
a.readAsDataURL(blob);
允许用户保存数据
除了显而易见的解决方案-打开新窗口,以您的dataURL作为URL,您还可以做其他两件事。
1. 使用fileSaver.js
文件保护程序可以使用预定义的文件名创建实际的文件保存对话框。它还可以退回到正常的dataURL方法。
2. 使用(实验性)URL.createObjectURL
这对于重用base64编码的数据非常有用。它为你的dataURL创建一个简短的URL:
console.log(URL.createObjectURL(blob));
//Prints: blob:http://stackoverflow.com/7c18953f-f5f8-41d2-abf5-e9cbced9bc42
不要忘记使用包含前导blob前缀的URL。我使用文档。身体:
你可以使用这个短URL作为AJAX目标,<脚本>源或< > href位置。你要负责破坏URL:
URL.revokeObjectURL('blob:http://stackoverflow.com/7c18953f-f5f8-41d2-abf5-e9cbced9bc42')
我自己也遇到了这个问题。
首先,稍微修改你的代码:
var download = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+"<"+this.gamesave.tagName+">"
+this.xml.firstChild.innerHTML
+"</"+this.gamesave.tagName+">";
this.loader.src = "data:application/x-forcedownload;base64,"+
btoa(download);
然后使用你最喜欢的web检查器,在指定this.loader的代码行上放置一个断点。Src,然后执行以下代码:
for (var i = 0; i < download.length; i++) {
if (download[i].charCodeAt(0) > 255) {
console.warn('found character ' + download[i].charCodeAt(0) + ' "' + download[i] + '" at position ' + i);
}
}
根据应用程序的不同,替换超出范围的字符可能有效,也可能无效,因为您将修改数据。请参阅MDN上关于使用btoa方法使用unicode字符的说明:
https://developer.mozilla.org/en-US/docs/Web/API/window.btoa
作为Stefan Steiger回答的补充:(作为评论看起来不太好)
扩展字符串原型:
String.prototype.b64encode = function() {
return btoa(unescape(encodeURIComponent(this)));
};
String.prototype.b64decode = function() {
return decodeURIComponent(escape(atob(this)));
};
用法:
var str = "äöüÄÖÜçéèñ";
var encoded = str.b64encode();
console.log( encoded.b64decode() );
注意:
正如评论中所述,不建议使用unescape,因为它将来可能会被删除:
警告:尽管unescape()并没有被严格弃用(就像“从Web标准中删除”一样),但它在ECMA-262标准的附件B中有定义,其介绍说明:
本附录中规定的所有语言特性和行为都有一个或多个不受欢迎的特性,如果没有遗留用法,将从本规范中删除。
注意:不要使用unescape来解码uri,而是使用decodeURI或decodeURIComponent来代替。