数据URIscheme和Internet Explorer 9错误

我在IE 6-9版本中使用RFC 2397数据urlscheme时遇到了问题。 使用当前版本的Safari,FF,Opera和Chrome时,下面的示例代码没有任何问题。

data:text/html;base64,PG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMDt1cmw9aHR0cDovL2dvb2dsZS5jb20vIj4g 

要么

 data:text/html,%3Cmeta%20http-equiv%3D%22refresh%22%20content%3D%220%3Burl%3Dhttp%3A//google.com/%22%3E%20 

如果上面的代码被粘贴在几乎所有的浏览器(不包括IE浏览器),它将导航到google.com,当试图与IE浏览器失败,并出现以下错误。

网页无法显示

最可能的原因是:

  • 本网页上的某些内容或文件需要您没有安装的程序。

你可以尝试一下:

在线search可用于查看此Web内容的程序。

重新input地址。

在检查生成的IE错误页面的页面源时,有一个链接引用了文件关联和协议。

协议types:

描述:UnKnown

Windows不能识别这个协议。

我意识到使用data:协议可能不是最直接的,或者在大多数情况下是最好的select,但是我必须将它用于这个特定的项目。

我已经search了一个解决scheme,并试图与IE浏览器希望是我的语法,但还没有find一个解决scheme的很多例子。

数据URI不能用于导航,编写脚本或在IE中填充框架或iframe元素。

根据http://msdn.microsoft.com/en-us/library/cc848897%28v=vs.85%29.aspx

数据URI仅支持以下元素和/或属性。

 object (images only) img input type=image link CSS declarations that accept a URL, such as background, backgroundImage, and so on. 

数据URI可以嵌套。

出于安全原因,数据URI仅限于下载的资源。 数据URI不能用于导航 ,编写脚本或填充框架或iframe元素。

数据URI不能超过32,768个字符。

资源数据必须正确编码; 否则,发生错误,资源未加载。 “#”和“%”字符必须进行编码,以及控制字符,非美国ASCII字符和多字节字符。

有关更多信息,请参阅RFC2397:“数据”URLscheme。

从Windows Internet Explorer 8或更高版本开始提供。**

对我来说,finddocument.execCommand是一个救命稻草。 它像其他一些示例一样使用iFrame ,但execCommand使“ Save Asfunction保持一致。

这是一个例子

 var getCsvFileForIE = function(target) { var csvData = target.attributes["data-csv"].value; if (navigator.appName === "Microsoft Internet Explorer") { csvData = decodeURIComponent(csvData); var iframe = document.getElementById('csvDownloadFrame'); iframe = iframe.contentWindow || iframe.contentDocument; csvData = 'sep=,\r\n' + csvData; iframe.document.open("text/html", "replace"); iframe.document.write(csvData); iframe.document.close(); iframe.focus(); iframe.document.execCommand('SaveAs', true, 'data.csv'); } else { if (console && console.log) { console.log('Trying to call getCsvFileForIE with non IE browser.'); } } }; 

我们为IE和所有其他浏览器使用标准的Data URI链接。 你可以看到更多细节的完整要点 。 给Andrew Blondeau一个帽子的方向


UPDATE

确定浏览器是否支持数据URI的更好方法

supportsDataUri = 'download' in document.createElement('a');

这也似乎IE浏览器仍然遇到问题。 对于IE10 +,您可能需要使用msSaveOrOpenBlob ,对于IE8 / 9,您仍然需要在iFrame执行execCommand

更新2

检测数据的urischeme有一个Modernizr问题 。 它引用另一个SO答案 。 一定要检查一下。

Internet Explorer不支持数据URI (资源有点过时)。 它有一些安全方面的考虑,虽然它可以防止恶意企图redirect用户,或者让黑客进行networking钓鱼,而不需要第三方脚本或托pipe资源。

这意味着你可以在JavaScript中使用它:

 <script src="data:text/javascript;base64;YWxlcnQoIldvcmtzIik7"></script> 

级联样式表(带或不带base64编码):

 <link rel="stylesheet" href="data:text/css;base64,Ym9keXtjb2xvcjpncmVlbn0="> <link rel="stylesheet" href="data:text/css,body%7Bcolor:green%7D"> 

甚至图像:

 <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4QBgRXhpZgAASUkqAAg AAAACADEBAgAHAAAAJgAAAGmHBAABAAAALgAAAAAAAABQaWNhc2EAAAMAAJAHAAQAAAAwMjIwAqAEAAE AAAAbAAAAA6AEAAEAAAAbAAAAAAAAAP/bAIQAAwICAwICAwMDAwQDAwQFCAUFBAQFCgcHBggMCgwMCwo LCw0OEhANDhEOCwsQFhARExQVFRUMDxcYFhQYEhQVFAEDBAQFBAUJBQUJFA0LDRQUFBUUFBQUFBQUDxQ QFBUUExUVFBQUEBUUFQ4UFBQUEhISDxURFQ8SFRQSEBAQDQ8P/8AAEQgAGwAbAwERAAIRAQMRAf/EABg AAAMBAQAAAAAAAAAAAAAAAAUHCAIG/8QAKxAAAQMDAwMDAwUAAAAAAAAAAQIDBAUGEQASIQciMQgTFEF RgRVhcaHD/8QAGQEAAwEBAQAAAAAAAAAAAAAABAUGBwMC/8QALxEAAQMCAgcHBQEAAAAAAAAAAQACAwQ RBSESMUFRYZHBEyJxobHR4RVDgfDxFP/aAAwDAQACEQMRAD8AGdeKdd3Um670bjz0waNQpzVKpVOWtSE uqSgKefIztKipQwSOU4wRjuBq6tj52h2YTbA8Nkp6UmMaLzzS1sz0ru1qqNyrkrqWIiMrfjsjctw4HGT wM/ngaEmxJjBaNqdRYPJpaczr8FTXRY1h7p9dVg1GpSZzNBkobYcec3qfgup9xjefqUqQ4n+ED651RYf Utla2UjMKBx6hdTvdEw2ac7JR13psz+rytkUqTv8AITq1bVZDNZo6ncCQFYFH9O1vS+lVrOW1bD0REtl uW8hi45Ty0hSAUkOrKlLyNvA27eBnCdZbUxNv3GjkFudDWvved55k9QpI9S0y7ujfqUk2jZ4bcaetuFP MSSFyENrW84h1zevcvOEgZzj9hnQ76aAQh0+Wezw1JjR1dVPO5kJuNxJ360Stj1LU/ooqREuuA9Krs4s LqM2A0lbDSACG0kDlRTlZKUjHJx5xplhjWui7mq+Xkk2PhxqgDrDRfxuUmL89awuO8KrUU202lDz3Z7K vbSpIASlW3ZwSACR9ydUsc/ZtDBs4qLkw4TPMjjmeCGSurEun2rRqJBvStJq5U6iSiLUZHx0BKRtQ2pT hJwPBASnggDxqUjDzdxBtx+PlaTpQEhha38DqegCM2PdL6apMrkyHKn1FuIiOuoyCpbiEA57nFLVkcnC OAST4OgqqMygMLsr6lQUZigvIxlstdv3pdbqsGy7nn1ym3pcEy3am06hwvsKZMYtrYQUZK1pVu2r5SkK APPGjIJXQQt7Jml/VJ4lCKmre50lj8JYVDopYQmu/GviZJYz2OtQS6lQ+4UlZB/B16+oz7YDzCB/wsH3 fJIx+W8qRKWXFbxIUQrPPCiB/QGmLNQQriS4lODo1Mk1/qBQaJUJcmVSXJrYXEW+v21dw8gHnQNaBHA6 Ros62tOaKV8kjY3OJbuWrXkya/wBV6z8ubMCn1y1OLjSnI61YXwNzaknaMDtzjgccDXKoPZUzdEDZsB9 UFGTJO7SO/wBV0kq3mRIcHzaue4+axLP+uk/bO3DkPZMxE3jzPuv/2Q=="> 

但是,您不能将这些与window.openiframe ,因为这些会导致一些非常危险的事情,包括使用数据URI的Phishing :

 <iframe src="data:text/html;base64,PGJ1dHRvbiBpZD0iX3BheXBhbCI+TG9nIGludG8gUGF5cG FsPC9idXR0b24+DQo8c2NyaXB0Pg0KICAgIF9wYXlwYWwuYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCB mdW5jdGlvbiAoKSB7DQogICAgICAgIGFsZXJ0KCJUaGlzIGNvdWxkIGhhdmUgYmVlbiB1Z2x5IGZvciB5 b3UuLi4iKTsNCiAgICB9LCBmYWxzZSk7DQo8L3NjcmlwdD4="></iframe> 

最后一个例子可能是PayPallogin屏幕的完整副本。 相反,它只是一个HTMLbutton,绑定了事件处理程序并监听点击。 类似的黑客可以通过window.open的方式来:

 window.open("data:text/html;base64,PHN0cm9uZz5XQVQhPzwvc3Ryb25nPg==", "OHAI"); 

因此,Internet Explorer 10支持此function,但它可以保护最终用户免受恶意使用的最终用户的侵害。 我相信微软会很乐意解除这个限制,如果他们确定一个更好的方法来保护他们的用户群。

在事情发生变化之前,您需要find另一种包含FLV文件的方式。 在附注上,你可能不希望在堆栈溢出的应用程序中共享像这样的实际数据

根据佛朗哥的答案在这里: CSV文件导出为IE

只需用它创build一个Blob对象

 //Save file if (isMicrosoftIE()) { csvData = decodeURIComponent(csv); if(window.navigator.msSaveBlob){ var blob = new Blob([csvData],{ type: "application/csv;charset=utf-8;"}); navigator.msSaveBlob(blob, filename); } } else { csvData = "data:application/csv;charset=utf-8," + encodeURIComponent(csv); $(this).attr({ "href": csvData, "target": "_blank", "download": filename }); } 

它适用于我!

这里解释了两种可选的解决scheme: http : //sparecycles.wordpress.com/2012/03/08/inject-content-into-a-new-iframe/

我可以告诉的主要区别在于,iframe与原始页面有相同的来源,这可能是不希望的(我不确定安全含义,例如引用者或cookie对于加载的资源可能是什么)。

使用javascript:scheme技术的一个例子是: http : //jsbin.com/uhenuz/4 (如果与https一起使用,则需要额外的Googlesearch和良好的testing来检查混合的https / http警告永远不会出现)。

我到这里时,正在寻找一种方法来检测数据uri支持文件(在我的情况下,PDF文件)。 检查图像支持的Modernizr方法还不够好,因为Internet Explorer 11和Edge 25支持,但不支持application / pdf等文件types。 Snekse的检查下载属性的方法适用于IE,但不适用于Edge。 最终,我使用AJAX调用编写了自己的function检测脚本,尝试打开数据URI并检查错误。 这是我使用的脚本(在IE 11,Edge 25,Firefox 46和Chrome 49中testing过):

 checkDataURISupport(function (checkResult) { if (checkResult) { alert('Files in data URIs are supported.'); } else { alert('Files in data URIs are NOT supported.'); } }) function checkDataURISupport(callback) { try { var request = new XMLHttpRequest(); request.onload = function reqListener() { callback(true); }; request.onerror = function reqListener() { callback(false); }; request.open('GET', 'data:application/pdf;base64,cw=='); request.send(); } catch (ex) { callback(false); } } 

更新

我意识到任何正在testing数据URI的代码是iframe支持也在testing支持在新窗口中打开数据URI。 因此,在这个SO答案中提到的解决scheme和Snekse的答案更新链接在技术上是优越的,我build议使用它而不是上面的代码。