读书人

CSSHttpRequest 应用记叙

发布时间: 2013-04-09 16:45:09 作者: rapoo

CSSHttpRequest 使用记叙

首先介绍下这个东西,说白了它跟jsonp很相似,

Like JavaScript includes, this works because CSS is not subject to the same-origin policy that affects XMLHttpRequest. CSSHttpRequest functions similarly to JSONP, and is limited to making GET requests. Unlike JSONP, untrusted third-party JavaScript cannot execute in the context of the calling page.

?

加粗的这句话是说 不像 jsonp在上下文中不信任的第三方js文件不能被执行,这个我没想明白...

?

/* CSSHttpRequestCopyright 2008 nb.io - http://nb.io/Licensed under Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.html*/(function(){    var chr = window.CSSHttpRequest = {};            chr.id = 0;    chr.requests = {};    chr.MATCH_ORDINAL = /#c(\d+)/;    chr.MATCH_URL = /url\("?data\:[^,]*,([^")]+)"?\)/;            chr.get = function(url, callback) {        var id = ++chr.id;        var iframe = document.createElement( "iframe" );        iframe.style.position = "absolute";        iframe.style.left = iframe.style.top = "-1000px";        iframe.style.width = iframe.style.height = 0;        document.documentElement.appendChild(iframe);        var r = chr.requests[id] = {            id: id,            iframe: iframe,            document: iframe.contentDocument || iframe.contentWindow.document,            callback: callback        };                r.document.open("text/html", false);        r.document.write("<html><head>");        r.document.write("<link rel='stylesheet' type='text/css' media='print, csshttprequest' href='" + chr.escapeHTML(url) + "' />");        r.document.write("</head><body>");        r.document.write("<script type='text/javascript'>");        r.document.write("(function(){var w = window; var p = w.parent; p.CSSHttpRequest.sandbox(w); w.onload = function(){p.CSSHttpRequest.callback('" + id + "');};})();");        r.document.write("</script>");        r.document.write("</body></html>");        r.document.close();    };            chr.sandbox = function(w) {    };                chr.callback = function(id) {        var r = chr.requests[id];        var data = chr.parse(r);        r.callback(data);        window.setTimeout(function() {            var r = chr.requests[id];            try { r.iframe.parentElement.removeChild(r.iframe); } catch(e) {};            delete chr.requests[id];        }, 0);    };        chr.parse = function(r) {        var data = [];                // Safari, IE and same-domain Firefox        try {            var rules = r.document.styleSheets[0].cssRules || r.document.styleSheets[0].rules;            for(var i = 0; i < rules.length; i++) {                try {                    var r = rules.item ? rules.item(i) : rules[i];                    var ord = r.selectorText.match(chr.MATCH_ORDINAL)[1];                    var val = r.style.backgroundImage.match(chr.MATCH_URL)[1];                    data[ord] = val;                } catch(e) {}            }        }                // catch same-domain exception        catch(e) {            r.document.getElementsByTagName("link")[0].setAttribute("media", "screen");            var x = r.document.createElement("div");            x.innerHTML = "foo";            r.document.body.appendChild(x);            var ord = 0;            try {                while(1) {                    x.id = "c" + ord;                    var style = r.document.defaultView.getComputedStyle(x, null);                    var bg = style["background-image"] || style.backgroundImage || style.getPropertyValue("background-image");                    var val = bg.match(chr.MATCH_URL)[1];                    data[ord] = val;                    ord++;                }            } catch(e) {}        }                return decodeURIComponent(data.join(""));    };            chr.escapeHTML = function(s) {        return s.replace(/([<>&""''])/g,            function(m, c) {                switch(c) {                    case "<": return "<";                    case ">": return ">";                    case "&": return "&";                    case '"': return """;                    case "'": return "'";                }                return c;            });    };})();

?

上面是实现的源代码,这个需要后端的支持,比如PHP的后端

<?php/** * CSSHttpRequest PHP Encoder * * @author Tim Akinbo <obnika@timakinbo.com>, Randy Reddig <ydnar@nb.io> * @version 1.2 * @license http://www.apache.org/licenses/LICENSE-2.0.html Apache License 2.0 * @copyright Copyright (c) 2008, Tim Akinbo */define('PREFIX', "data:,");define('LENGTH', 2000 - strlen(PREFIX)); # Internet Explorer 2KB URI limit (http://support.microsoft.com/kb/208427)function encode($string) {$quoted = rawurlencode($string);$out = "";for ($i = 0, $n = 0; $i < strlen($quoted); $i += LENGTH, $n++) {$out .= "#c" . $n . "{background:url(" . PREFIX . substr($quoted, $i, LENGTH) . ");}\n";}return $out;}/* unit test */if(STDIN) {    $string = file_get_contents("php://stdin", "r");    echo encode($string);}?>

?官网:

http://nb.io/hacks/csshttprequest

?

感觉还行,其实就是使用 dom元素的 url: data 的机制来实现的, dom这种功能还可以实现一种 本地存储的实现,有兴趣的可以试试

读书人网 >CSS

热点推荐