使用.cssRules访问跨域样式表

Mir*_*cea 24 jquery cross-domain

当我尝试访问外部域上托管的一些CSS文件时,我在Firebug中收到此错误:

Security error" code: "1000
rules = styleSheets[i].cssRules;
Run Code Online (Sandbox Code Playgroud)

我使用的代码是:

$(document).ready(function () {
    $("p").live('mousedown', function getCSSRules(element) {
        element = $(this);
        var styleSheets = document.styleSheets;
        var matchedRules = [],
            rules, rule;
        for (var i = 0; i < styleSheets.length; i++) {
            rules = styleSheets[i].cssRules;
            for (var j = 0; j < rules.length; j++) {
                rule = rules[j];
                if (element.is(rule.selectorText)) {
                    matchedRules.push(rule.selectorText);
                }
            }
        }
        alert(matchedRules);
    });
});
Run Code Online (Sandbox Code Playgroud)

有没有办法解决这个问题,除了移动同一域上的所有CSS文件?

小智 14

这个问题的唯一真正解决方案是CORS首先加载你的CSS.通过使用CORS XMLHttpRequest从外部域加载CSS,然后通过以下方式将responseText(在本例中实际为responseCSS)注入到页面中:

function loadCSSCors(stylesheet_uri) {
  var _xhr = global.XMLHttpRequest;
  var has_cred = false;
  try {has_cred = _xhr && ('withCredentials' in (new _xhr()));} catch(e) {}
  if (!has_cred) {
    console.error('CORS not supported');
    return;
  }
  var xhr = new _xhr();
  xhr.open('GET', stylesheet_uri);
  xhr.onload = function() {
    xhr.onload = xhr.onerror = null;
    if (xhr.status < 200 || xhr.status >= 300) {
      console.error('style failed to load: ' + stylesheet_uri);
    } else {
      var style_tag = document.createElement('style');
      style_tag.appendChild(document.createTextNode(xhr.responseText));
      document.head.appendChild(style_tag);
    }
  };
  xhr.onerror = function() {
      xhr.onload = xhr.onerror = null;
      console.error('XHR CORS CSS fail:' + styleURI);
  };
  xhr.send();
}
Run Code Online (Sandbox Code Playgroud)

这样,浏览器将CSS文件解释为来自与主页面响应相同的源域,现在您可以访问样式表的cssRules属性.


Joh*_*der 10

从2013年开始,您可以在-Element上设置"crossorigin"属性,<link>以通知浏览器此CSS受信任(Mozilla,W3).为此,托管CSS的服务器必须设置Access-Control-Allow-Origin: *标头.

之后,您可以通过Javascript访问其规则.

  • @Gili与您的陈述相反,`crossOrigin`**是HTML5中的标准化属性([自2012年11月起](http://lists.whatwg.org/pipermail/commit-watchers-whatwg.org/2012/006700 .html)),它不仅在Firefox中实现,还在Chrome中实现(自25.0.1318.0版本(2012年11月)起,[crbug.com/178787](http://code.google.com/p/chromium/issues/detail?id = 178787))和Opera 15. (2认同)
  • @Gill您正在查看规范的错误部分.http://www.w3.org/TR/html5/links.html指定了"链接"的概念,而不是"<link>"元素.在WHATWG和W3的规范中提到了`<link crossorigin>`http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#the-link-element和http: //www.w3.org/TR/html5/document-metadata.html#the-link-element (2认同)