Chrome应用程序,后台脚本在限制范围内运行

时间:2012-06-14 16:20:56

标签: javascript google-chrome-extension

我们有一个可在台式机和支持互联网的电视上运行的Web应用程序。目前,我们正在使用User-Agent标头来确定要提供的接口。

我现在的任务是让电视界面可以从桌面浏览器访问,而不会阻止对桌面网站的访问,因此我认为将其包装起来就像Chrome应用程序一样可以解决这个问题,但是有一些问题。

打包应用方法

我创建了一个打包的应用程序,其中包含一个iframe,用于加载主网站和一些javascript,使用chrome.webRequest.onBeforeSendHeaders函数覆盖User-Agent。

的manifest.json

{
    "app": {
        "launch": {
            "local_path": "index.html"
        }
    },
    "permissions": [
        "webRequest", "webRequestBlocking", "cookies",
        "*://my.site.url/*"
    ]
}

的index.html

<html>
    <head>
        <script src="main.js"></script>
    </head>
    <body>
        <iframe src="http://my.site.url"></iframe>
    </body>
</html>

main.js

chrome.webRequest.onBeforeSendHeaders.addListener(
    function(details) 
    {
        var headers = details.requestHeaders;

        for (var i = 0; i < headers.length; ++i) 
        {
            if (headers[i].name === 'User-Agent') 
            {
                headers[i].value += " Chromebox"
                break;
    }
        }
        return {requestHeaders: headers};
    }, 
    {
        urls: ["*://my.site.url/*"]
    }, 
    ["blocking", "requestHeaders"]
);

问题

  • 我必须允许加载整个网站 在iframe内部,打开可能的clickjacking
  • 当应用程序打开时,它还会在导航到另一个选项卡中的主站点时触发onBeforeSendHeaders侦听器,从而导致修改User-Agent并将所有对该站点的请求重定向到电视界面。

托管应用程序方法

我创建了一个托管应用,其中起始网址指向主网站,并创建了一个运行javascript以覆盖用户代理的后台网页。

的manifest.json

{
    "app": {
        "launch": {
            "web_url": "http://my.site.url"
        }
    },
    "background_page": "https://my.site.url/chromebox/index.html",
    "permissions": [
        "webRequest", "webRequestBlocking", "background",
        "*://my.site.url/*"
    ]
}

的index.html

<html><script src="main.js"></script></html>

问题

  • 安装背景页面后,javascript始终在运行,因此用户始终会被重定向到电视网站

理想的解决方案是托管应用程序,其背景页面仅在应用程序打开时运行且onBeforeSendHeaders侦听器不会影响chrome应用程序之外的任何请求。

有没有人知道如何实现这个目标?

1 个答案:

答案 0 :(得分:0)

我认为我没有直接解决您的问题,但如果我这样做了,那么您的托管应用方法就是main.js

function parse_url(str,component){var key=['source','scheme','authority','userInfo','user','pass','host','port','relative','path','directory','file','query','fragment'],ini=(this.php_js&&this.php_js.ini)||{},mode=(ini['phpjs.parse_url.mode']&&ini['phpjs.parse_url.mode'].local_value)||'php',parser={php:/^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/};var m=parser[mode].exec(str),uri={},i=14;while(i--){if(m[i]){uri[key[i]]=m[i];}}
if(component){return uri[component.replace('PHP_URL_','').toLowerCase()];}
if(mode!=='php'){var name=(ini['phpjs.parse_url.queryKey']&&ini['phpjs.parse_url.queryKey'].local_value)||'queryKey';parser=/(?:^|&)([^&=]*)=?([^&]*)/g;uri[name]={};uri[key[12]].replace(parser,function($0,$1,$2){if($1){uri[name][$1]=$2;}});}
delete uri.source;return uri;}

chrome.webRequest.onBeforeSendHeaders.addListener(function(details){
    if(!details.requestHeaders) return details; // skip parsing if missing request headers
    var domain = parse_url(details.url,'host');
    if(host.indexOf('my.site.com')!==0) return details; // skip parsing if it doesn't go to your site
    host=host.split('/'); if(host[1] && host[1]!=='') return details; // skip parsing if it doesn't go to the index

    var headers = details.requestHeaders;
    for(var i in headers){
        if(!headers[i] || !headers[i].name || !headers[i].value) continue;
        if(headers[i].name!=='string') continue;
        if(headers[i].name.toLowerCase()!=='user-agent') continue;

        details.requestHeaders[i].value += ' Chromebox'
        break;
    }

    return details; //  OK BOSS
});

Parse_url() function stolen from PHP.js