Data URI scheme and Internet Explorer 9 Errors
I'm having a problem using the RFC 2397 data url scheme with IE versions 6-9. My sample code below works without problem when using current versions of Safari, FF, Opera and Chrome.
data:text/html;base64,PG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMDt1cmw9aHR0cDovL2dvb2dsZS5jb20vIj4g
or
data:text/html,%3Cmeta%20http-equiv%3D%22refresh%22%20content%3D%220%3Burl%3Dhttp%3A//google.com/%22%3E%20
If the above code is pasted in almost any browser excluding IE it will navigate to google.com, when attempting with IE it fails with the following error.
The webpage cannot be displayed
Most likely cause:
- Some content or files on this webpage require a program that you don't have installed.
What you can try:
Search online for a program you can use to view this web content.
Retype the address.
When inspecting the page source of the IE error page generated there is a link that makes reference to File Associations and protocols.
Protocol Type:
Description: UnKnown
Windows does not recognize this Protocol.
I realize that using the data: protocol is probably not the开发者_JS百科 most straight forward or in most cases the best option, but I must use it for this particular project.
I have searched all over for a solution and tried many examples with IE hoping it was my syntax but have yet found a solution.
Data URIs cannot be used for navigation, for scripting, or to populate frame or iframe elements in IE.
According to http://msdn.microsoft.com/en-us/library/cc848897%28v=vs.85%29.aspx:
Data URIs are supported only for the following elements and/or attributes.
object (images only) img input type=image link CSS declarations that accept a URL, such as background, backgroundImage, and so on.
Data URIs can be nested.
For security reasons, data URIs are restricted to downloaded resources. Data URIs cannot be used for navigation, for scripting, or to populate frame or iframe elements.
Data URIs cannot be larger than 32,768 characters.
The resource data must be properly encoded; otherwise, an error occurs and the resource is not loaded. The "#" and "%" characters must be encoded, as well as control characters, non-US ASCII characters, and multibyte characters.
For more information, see RFC2397: The "data" URL scheme.
Available as of Windows Internet Explorer 8 or later.**
For me, finding document.execCommand
was a life saver. It uses the iFrame
like some of the other examples, but the execCommand
makes the Save As
functionality consistent.
Here's an example
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.');
}
}
};
We do this for IE and for all other browsers we use the standard Data URI link. You can see the full gist for more details. A hat tip to Andrew Blondeau for the direction.
UPDATE
A better way to determine if the browser support a Data URI
supportsDataUri = 'download' in document.createElement('a');
It also seems like IE still runs into issues. For IE10+ you might need to use msSaveOrOpenBlob
and for IE8/9 you still need to do the execCommand
in an iFrame
.
UPDATE 2
There is a Modernizr issue for detecting data uri scheme. It references another SO answer. Be sure to also check those out.
Internet Explorer does support Data URIs (resource is a bit out of date). It has some security considerations though which prevent it from allowing malicious attempts to redirect users, or otherwise allow hackers to engage in phishing without requiring 3rd party scripts or hosted resources.
This means you can use it with JavaScript:
<script src="data:text/javascript;base64;YWxlcnQoIldvcmtzIik7"></script>
Cascading Style Sheets (with, or without base64 encoding):
<link rel="stylesheet" href="data:text/css;base64,Ym9keXtjb2xvcjpncmVlbn0=">
<link rel="stylesheet" href="data:text/css,body%7Bcolor:green%7D">
Or even images:
<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==">
You cannot, however, use these with window.open
or iframe
, as these would allow some very dangerous things, including Phishing with Data URIs:
<iframe src="data:text/html;base64,PGJ1dHRvbiBpZD0iX3BheXBhbCI+TG9nIGludG8gUGF5cG
FsPC9idXR0b24+DQo8c2NyaXB0Pg0KICAgIF9wYXlwYWwuYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCB
mdW5jdGlvbiAoKSB7DQogICAgICAgIGFsZXJ0KCJUaGlzIGNvdWxkIGhhdmUgYmVlbiB1Z2x5IGZvciB5
b3UuLi4iKTsNCiAgICB9LCBmYWxzZSk7DQo8L3NjcmlwdD4="></iframe>
This last example could very well have been a full-on replica of the PayPal login screen. Instead, it's just an HTML button with an event-handler bound and listening for clicks. Similar hackery could come by way of window.open
:
window.open("data:text/html;base64,PHN0cm9uZz5XQVQhPzwvc3Ryb25nPg==", "OHAI");
So Internet Explorer 10 supports this feature, but it protects the end-user from those who would use it maliciously. I'm sure Microsoft will gladly lift this restriction when and if they determine a better way to protect their user-base.
Until things change, you need to find another way to include your FLV files. On a side-note, you may not want to share actual data like this from your application on Stack Overflow.
According to Franco's answer here: CSV file export For IE
Just create a Blob object with it
//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
});
}
And it works for me!
Two alternative solutions are explained here: http://sparecycles.wordpress.com/2012/03/08/inject-content-into-a-new-iframe/
The main difference I can tell is that the iframe has the same origin as the original page, which might not be desired (I am unsure of security implications e.g. what the referer or cookies might be for loaded resources).
An example of using the javascript: scheme technique is here: http://jsbin.com/uhenuz/4 (If used with https would need extra googling and good testing to check that mixed https/http warning can never come up.)
I got here while I was looking for a way to feature detect for data uri support of files (PDFs in my case). The Modernizr approach of checking for image support was not good enough since Internet Explorer 11 and Edge 25 do support that but don't support file types like application/pdf. Snekse's approach of checking for the download attribute worked on IE but not Edge. Eventually, I wrote my own feature detection script using an AJAX call to attempt to open a data URI and checking for errors. This is the script I used (tested in IE 11, Edge 25, Firefox 46, and Chrome 49):
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);
}
}
Update
I realized that any code that is testing for data URI is iframe support is also testing for supporting opening a data URI in a new window. Thus, the solution mentioned in this SO answer and linked to in Snekse's answer update is technically superior and I would recommend using it instead of the above code.
精彩评论