Detect if browser supports data uri scheme with iframes

后端 未结 2 2064
借酒劲吻你
借酒劲吻你 2020-12-19 13:17

Internet Explorer does not support the data uri scheme for iframe urls (see http://msdn.microsoft.com/en-us/library/cc848897%28v=vs.85%29.aspx). Other browsers do. As browse

2条回答
  •  萌比男神i
    2020-12-19 13:47

    If the onload event of the iframe with a data: URI fires, the browser supports data: URIs. Otherwise, the browser doesn't support data: URIs.

    The example code also checks if scripting is allowed from a data: URI by sending a message from the iframe to the parent window.

    Working code

    var iframeDataURISupport = { checked: false, supported: false, scriptingSupported: false };
    
    function iframesSupportDataURIs(callback) {
        if (!iframeDataURISupport.checked) {
            var iframe = document.createElement('iframe'), alreadyCalled = false, done = function () {
                if (!alreadyCalled) {
                    alreadyCalled = true;
    
                    document.body.removeChild(iframe);
    
                    console.log(iframeDataURISupport);
    
                    callback && callback(iframeDataURISupport);
                }
            }, previousMessageHandler = window.onmessage, dataURI = 'data:text/html,<' + 'script>window.parent.postMessage("data: URIs supported", "*");<' + '/script>';
    
            window.onmessage = function (e) {
                if (e.data === 'data: URIs supported') {
                    window.onmessage = previousMessageHandler;
    
                    iframeDataURISupport.supported = true;
                    iframeDataURISupport.scriptingSupported = true;
    
                    done();
                } else {
                    window.onmessage.apply(this, arguments);
                }
            };
    
            iframe.src = dataURI;
            iframe.setAttribute('style', 'display: inline-block; width: 0; height: 0; overflow: hidden; border: 0 none; padding: 0; margin: 0;'.replace(/;/g, ' !important;'));
    
            iframe.onload = function (e) {
                if (iframe.src === dataURI) {
                    iframeDataURISupport.supported = true;
    
                    setTimeout(done, 100);
                } else done();
            };
    
            document.body.appendChild(iframe);
    
            setTimeout(done, 500);
        } else {
            setTimeout(function () {
                callback && callback(iframeDataURISupport);
            }, 5);
        }
    };
    

    Usage

    iframesSupportDataURIs(function (details) {
        alert('This browser ' + (details.supported ? 'supports' : 'does not support') + ' data: URIs. It ' + (details.scriptingSupported ? 'also supports' : 'does not support') + ' scripting from data: URIs');
    });
    

    If you want more advanced control, you can call it like this:

    iframeDataURISupport.checked ? functionName(iframeDataURISupport) : iframesSupportDataURIs(functionName);
    

    Demo

    Play with it on JSFiddle.

提交回复
热议问题