it-swarm.it

Schema URI dati ed errori di Internet Explorer 9

Sto riscontrando un problema nell'uso dello schema URL di dati RFC 2397 con le versioni IE 6-9. Il mio codice di esempio riportato di seguito funziona senza problemi quando si utilizzano le versioni correnti di Safari, FF, Opera e Chrome.

data:text/html;base64,PG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMDt1cmw9aHR0cDovL2dvb2dsZS5jb20vIj4g

o

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

Se il codice sopra riportato viene incollato in quasi tutti i browser escluso IE, l'utente navigerà su google.com, quando tenta con IE fallisce con il seguente errore.

La pagina Web non può essere visualizzata

Molto probabilmente causa:

  • Alcuni contenuti o file su questa pagina web richiedono un programma che non hai installato.

Cosa puoi provare:

Cerca online un programma che puoi utilizzare per visualizzare questo contenuto web. 

Riscrivi l'indirizzo.

Quando si controlla l'origine della pagina della pagina di errore IE generata, esiste un collegamento che fa riferimento a Associazioni di file e protocolli.

Tipo di protocollo: 

Descrizione: UnKnown

Windows non riconosce questo protocollo.

Mi rendo conto che usare i dati: il protocollo non è probabilmente il più diretto o nella maggior parte dei casi l'opzione migliore, ma devo usarlo per questo particolare progetto. 

Ho cercato dappertutto una soluzione e ho provato molti esempi con IE sperando che fosse la mia sintassi ma ho ancora trovato una soluzione.

22
DaveCS

Gli URI dati non possono essere utilizzati per la navigazione, per lo scripting o per popolare elementi frame o iframe in IE.

Secondo http://msdn.Microsoft.com/en-us/library/cc848897%28v=vs.85%29.aspx :

Gli URI di dati sono supportati solo per i seguenti elementi e/o attributi .

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

Gli URI di dati possono essere annidati.

Per motivi di sicurezza, gli URI dei dati sono limitati alle risorse Scaricate.Gli URI dati non possono essere usati per la navigazione, per lo scripting, o Per popolare elementi frame o iframe.

Gli URI dei dati non possono essere maggiori di 32.768 caratteri.

I dati delle risorse devono essere correttamente codificati; in caso contrario, si verifica un errore e la risorsa non viene caricata. I caratteri "#" e "%" devono essere codificati , Nonché caratteri di controllo, caratteri ASCII non statunitensi e caratteri multibyte .

Per ulteriori informazioni, consultare RFC2397: lo schema di URL "dati".

Disponibile da Windows Internet Explorer 8 o successivo. **

24
DaveCS

Per me, trovare document.execCommand è stato un risparmiatore di vita. Utilizza iFrame come alcuni degli altri esempi, ma execCommand rende coerente la funzionalità Save As.

Ecco un esempio 

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.');
    }
  }
};

Facciamo questo per IE e per tutti gli altri browser utilizziamo il collegamento URI dati standard. Puoi vedere il Gist completo per maggiori dettagli. Una punta di cappello per Andrew Blondeau per la direzione .


UPDATE

Un modo migliore per determinare se il browser supporta un URI di dati

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

Sembra anche che IE ricada ancora nei problemi. Per IE10 + potrebbe essere necessario utilizzare msSaveOrOpenBlob e per IE8/9 è ancora necessario eseguire execCommand in un iFrame.

AGGIORNAMENTO 2

Esiste un problema Modernizr per il rilevamento dello schema uri di dati. Fa riferimento a altro SO answer . Assicurati di controllare anche quelli fuori.

16
Snekse

Internet Explorer supporta URI di dati (la risorsa è un po 'obsoleta). Tuttavia, ha alcune considerazioni sulla sicurezza che impediscono ai tentativi maliziosi di reindirizzare gli utenti o consentire in altro modo agli hacker di dedicarsi al phishing senza richiedere script di terze parti o risorse ospitate.

Questo significa che puoi usarlo con JavaScript:

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

Fogli di stile CSS (con o senza codifica Base64):

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

O anche immagini:

<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==">

Tuttavia, non è possibile utilizzarli con window.open o iframe, in quanto ciò consentirebbe alcune cose molto pericolose, tra cui Phishing con URI di dati :

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

Quest'ultimo esempio potrebbe benissimo essere una replica completa della schermata di login di Paypal. Invece, è solo un pulsante HTML con un gestore di eventi legato e in ascolto per i clic. Un hackery simile potrebbe provenire da window.open:

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

Internet Explorer 10 supporta questa funzione, ma protegge l'utente finale da chi lo utilizza malintenzionato. Sono sicuro che Microsoft risolverà con piacere questa restrizione quando e se determineranno un modo migliore per proteggere la propria base di utenti.

Finché le cose non cambiano, devi trovare un altro modo per includere i tuoi file FLV. Su una nota a margine, potresti non voler condividere dati effettivi come questo dalla tua applicazione su Stack Overflow.

12
Sampson

Secondo la risposta di Franco qui: Esportazione file CSV per IE

Basta creare un oggetto Blob con esso

//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
    });
}

E funziona per me!

6
abla

Qui sono spiegate due soluzioni alternative: http://sparecycles.wordpress.com/2012/03/08/inject-content-into-a-newewifficame/

La differenza principale che posso dire è che l'iframe ha la stessa origine della pagina originale, il che potrebbe non essere desiderato (non sono sicuro delle implicazioni sulla sicurezza, ad esempio cosa potrebbero essere i referer oi cookie per le risorse caricate).

Un esempio di utilizzo della tecnica javascript: scheme è qui: http://jsbin.com/uhenuz/4 (Se utilizzato con https, è necessario un googling extra e un buon test per verificare che l'avviso misto https/http non possa mai venire su.)

0
robocat

Sono arrivato mentre stavo cercando un modo per rilevare il supporto dei dati uri (file PDF nel mio caso). L'approccio Modernizr per il controllo del supporto delle immagini non era abbastanza buono da quando Internet Explorer 11 e Edge 25 lo supportano ma non supportano tipi di file come application/pdf. L'approccio di Snekse per il controllo dell'attributo download ha funzionato su IE ma non su Edge. Alla fine, ho scritto il mio script di rilevamento delle funzioni utilizzando una chiamata AJAX per tentare di aprire un URI di dati e verificare la presenza di errori. Questo è lo script che ho usato (testato in IE 11, Edge 25, Firefox 46 e 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);
    }
}

Aggiornamento

Mi sono reso conto che qualsiasi codice che sta testando l'URI dei dati è il supporto iframe sta anche testando per supportare l'apertura di un URI di dati in una nuova finestra. Pertanto, la soluzione menzionata in this SO answer e collegata all'aggiornamento della risposta di Snekse è tecnicamente superiore e suggerirei di utilizzarla al posto del codice precedente.

0
Chris