在Chrome扩展中读取CSS文档

在Chrome扩展中读取CSS文档,css,google-chrome,google-chrome-extension,Css,Google Chrome,Google Chrome Extension,我正在尝试使用chrome扩展阅读CSS页面。这是我的内容脚本中的内容: var allSheets = document.styleSheets; for (var i = 0; i < allSheets.length; ++i) { var sheet = allSheets[i]; var src = sheet.href; var rules = sheet.cssRules || sheet.rules; }

我正在尝试使用chrome扩展阅读CSS页面。这是我的内容脚本中的内容:

   var allSheets = document.styleSheets;
     for (var i = 0; i < allSheets.length; ++i) {
      var sheet = allSheets[i];
          var src = sheet.href;
      var rules = sheet.cssRules || sheet.rules;
     }
var allSheets=document.styleSheets;
对于(变量i=0;i

出于某种原因,规则总是空的。我确实得到了'src'变量中使用的所有CSS文件。但是规则总是无效的。。当我在HTML页面上尝试将其作为单独的javascript时,它就可以工作了。但是当我把它放到我的chrome扩展的内容脚本中时失败了。有人能告诉我原因吗?

我只是猜测一下,但由于chrome扩展是基于Javascript的,它们可能会有跨域问题。当以编程方式试图从另一个域获取样式表时,Chrome会将规则和cssRules设置为null。

这就是原因,但出于乐趣和兴趣(以前从未对样式表做过任何事情),我想我应该怎么做……
manifest.json

{
    "name": "Get all css rules in stylesheets",
    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "js" : ["myscript.js"],
            "run_at":"document_end"
        }
    ],
    "permissions": [
        "tabs", "<all_urls>"
    ],
    "version":"1.0"
}
// Create the div we use for communication
 var comDiv = document.createElement('div');
 comDiv.setAttribute("id", "myCustomEventDiv");
 document.body.appendChild(comDiv);

// Utitlity function to insert some js into the page, execute it and then remove it
function exec(fn) {
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.textContent = '(' + fn + ')();';
    document.body.appendChild(script); // run the script
    document.body.removeChild(script); // clean up
}


// function that gets inserted into the page
// iterates through all style sheets and collects their rules
// then sticks them in the comDiv and dispatchs the event that the content script listens for
getCSS=function (){
   var rules = '';

   // Create the event that the content script listens for
   var customEvent = document.createEvent('Event');
   customEvent.initEvent('myCustomEvent', true, true);

   var hiddenDiv = document.getElementById('myCustomEventDiv');
   var rules ='';
   var allSheets = document.styleSheets;
   for (var i = 0; i < allSheets.length; ++i) {
      var sheet = allSheets[i];
      for (var z = 0; z <= sheet.cssRules.length-1; z++) {
         rules = rules +'\n'+ sheet.cssRules[z].cssText;
      }
   }
   hiddenDiv.innerText = rules;
   hiddenDiv.dispatchEvent(customEvent);
}

// puts the rules back in the page in a style sheet that the content script can iterate through
// youd probably do most of this in the injected script normally and pass your results back through the comDiv....Im just having fun
document.getElementById('myCustomEventDiv').addEventListener('myCustomEvent', function() {
   var eventData = document.getElementById('myCustomEventDiv').innerText;
   document.getElementById('myCustomEventDiv').innerText='';

   var style = document.createElement('style');
   style.type = 'text/css';
   style.innerText=eventData;
   style = document.head.appendChild(style);
      var sheet = document.styleSheets[document.styleSheets.length-1];
      for (var z = 0; z <= sheet.cssRules.length-1; z++) {
         console.log(sheet.cssRules[z].selectorText +' {\n');
         for (var y = 0; y <= sheet.cssRules[z].style.length-1; y++) {
            console.log('  '+sheet.cssRules[z].style[y] + ' : ' + sheet.cssRules[z].style.getPropertyValue(sheet.cssRules[z].style[y])+';\n');
         };
         console.log('}\n');
      };

   // Clean up
   document.head.removeChild(style);
   document.body.removeChild(document.getElementById('myCustomEventDiv'));
});

exec(getCSS);
{
“名称”:“获取样式表中的所有css规则”,
“内容脚本”:[
{
“匹配项”:[“”],
“js”:[“myscript.js”],
“运行时间”:“文档结束”
}
],
“权限”:[
“制表符”
],
“版本”:“1.0”
}
myscript.js

{
    "name": "Get all css rules in stylesheets",
    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "js" : ["myscript.js"],
            "run_at":"document_end"
        }
    ],
    "permissions": [
        "tabs", "<all_urls>"
    ],
    "version":"1.0"
}
// Create the div we use for communication
 var comDiv = document.createElement('div');
 comDiv.setAttribute("id", "myCustomEventDiv");
 document.body.appendChild(comDiv);

// Utitlity function to insert some js into the page, execute it and then remove it
function exec(fn) {
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.textContent = '(' + fn + ')();';
    document.body.appendChild(script); // run the script
    document.body.removeChild(script); // clean up
}


// function that gets inserted into the page
// iterates through all style sheets and collects their rules
// then sticks them in the comDiv and dispatchs the event that the content script listens for
getCSS=function (){
   var rules = '';

   // Create the event that the content script listens for
   var customEvent = document.createEvent('Event');
   customEvent.initEvent('myCustomEvent', true, true);

   var hiddenDiv = document.getElementById('myCustomEventDiv');
   var rules ='';
   var allSheets = document.styleSheets;
   for (var i = 0; i < allSheets.length; ++i) {
      var sheet = allSheets[i];
      for (var z = 0; z <= sheet.cssRules.length-1; z++) {
         rules = rules +'\n'+ sheet.cssRules[z].cssText;
      }
   }
   hiddenDiv.innerText = rules;
   hiddenDiv.dispatchEvent(customEvent);
}

// puts the rules back in the page in a style sheet that the content script can iterate through
// youd probably do most of this in the injected script normally and pass your results back through the comDiv....Im just having fun
document.getElementById('myCustomEventDiv').addEventListener('myCustomEvent', function() {
   var eventData = document.getElementById('myCustomEventDiv').innerText;
   document.getElementById('myCustomEventDiv').innerText='';

   var style = document.createElement('style');
   style.type = 'text/css';
   style.innerText=eventData;
   style = document.head.appendChild(style);
      var sheet = document.styleSheets[document.styleSheets.length-1];
      for (var z = 0; z <= sheet.cssRules.length-1; z++) {
         console.log(sheet.cssRules[z].selectorText +' {\n');
         for (var y = 0; y <= sheet.cssRules[z].style.length-1; y++) {
            console.log('  '+sheet.cssRules[z].style[y] + ' : ' + sheet.cssRules[z].style.getPropertyValue(sheet.cssRules[z].style[y])+';\n');
         };
         console.log('}\n');
      };

   // Clean up
   document.head.removeChild(style);
   document.body.removeChild(document.getElementById('myCustomEventDiv'));
});

exec(getCSS);
//创建用于通信的div
var comDiv=document.createElement('div');
setAttribute(“id”、“myCustomEventDiv”);
文件.正文.附件(comDiv);
//Utitlity函数将一些js插入页面,执行它,然后删除它
职能执行官(fn){
var script=document.createElement('script');
setAttribute(“类型”、“应用程序/javascript”);
script.textContent='('+fn+')();';
document.body.appendChild(脚本);//运行脚本
document.body.removeChild(脚本);//清理
}
//插入到页面中的函数
//遍历所有样式表并收集它们的规则
//然后将它们粘贴到comDiv中,并发送内容脚本侦听的事件
getCSS=函数(){
var规则=“”;
//创建内容脚本侦听的事件
var customEvent=document.createEvent('Event');
initEvent('myCustomEvent',true,true);
var hiddenDiv=document.getElementById('myCustomEventDiv');
var规则=“”;
var allSheets=document.styleSheets;
对于(变量i=0;i对于(var z=0;z回答很晚,但我认为我可以提供帮助。访问受CORs保护的外部工作表的cssRules的一种方法是使用Yahoo的YQL服务。我已将其合并到Chrome的开发者工具扩展中,用于捕获页面片段的样式和标记。该扩展位于中,并且已启用

从Github获取源代码并查看content.js脚本以了解YQL是如何使用的。基本上,您将对YQL进行AJAX调用,它将为您获取CSS。您需要获取CSS内容,并将其作为嵌入式样式标记注入页面,或者使用JavaScript解析CSS(有一些用于此目的的库)。如果选择将新样式块重新注入到文档中,请确保将新样式块设置为“禁用”,以免影响页面的呈现

扩展本身可能对您有用:


要获取所有外部css和所有内部css文件,您可以使用devtools API。如果您想在chrome扩展中使用它,您需要将devtool挂接到chrome扩展中。此代码可以工作

chrome.devtools.panels.create(
    'my chrome extension',
    'icon.png',
    'index.html',
     function(panel) {
        var initial_resources = {};

        // collect our current resources
        chrome.devtools.inspectedWindow.getResources(function(resources) {
            for (var i = 0, c = resources.length; i < c; i++) {
                if (resources[i].type == 'stylesheet') {
                    // use a self invoking function here to make sure the correct
                    // instance of `resource` is used in the callback
                    (function(resource) {
                        resource.getContent(function(content, encoding) {
                            initial_resources[resource.url] = content;
                        });
                    })(resources[i]);
                }
            }
        });
    }
);
chrome.devtools.panels.create(
“我的chrome扩展”,
“icon.png”,
“index.html”,
功能(面板){
var initial_resources={};
//收集我们现有的资源
chrome.devtools.inspectedWindow.getResources(函数(资源){
for(var i=0,c=resources.length;i
我已经在开发者工具栏中测试了您的代码,我可以看到“cssRules”和“rules”属性始终为空。更重要的是,您想实现什么?阅读所有CSS并解析它们,然后处理CSS属性。不要装出迂腐的样子,但您有“匹配项”吗正确设置?你能将它设置为“*”并看看会发生什么吗?哦..明白..是..将它设置为:“匹配”:[“http://*/*”,“https://*/*”],我也遇到了问题。目前我不知道,只能使用xmlhttprequest再次加载它并检索响应文本。这不是真的,这是一个安全风险。你试图通过阅读规则来实现什么?我试图读取所有CSS属性并对这些属性执行一些只读操作。所以你说在ch上没有办法做到这一点rome插件?;”(如果您可以控制扩展与之通信的服务器,那么这是可能的。否则,除了在DOM中迭代对象并计算它们的样式之外,恐怕您运气不好。Chrome允许您在页面脚本中访问DOM。这太酷了:)…我确实试过,但出于某种原因,外部CSS不可读。只有内联的才可读。知道为什么吗?但我喜欢这种方法..太棒了:)对于内部样式表,您可以直接访问其内容。对于外部样式表,您不能读取其内容,因为存在安全风险。请检查:chrome.devtools.*API模块仅适用于devtools窗口中加载的页面。内容脚本和其他e