1

我正在制作一个非常简单的 Chrome 扩展程序,它将 http 协议上的页面重定向到 https 协议(如果存在)。我正在调试,我发现了 facebook,它同时具有 http 和 https。

代码在这里:

function redirect() {    
    chrome.tabs.query({active: true}, function(tabArray) {  
        var currentURL = tabArray[0].url;               //http://facebook.com
        var httpsURL = generateSSL(currentURL);         //https://facebook.com
        if(httpsURL == currentURL){
            console.log(currentURL+" is already on HTTPS");
            chrome.browserAction.setIcon({path:"../images/padlock_green.png"});
        } else if(checkSSL(httpsURL)){                      
            chrome.tabs.update(tabArray[0].id, {url: httpsURL});
            chrome.browserAction.setIcon({path:"../images/padlock_green.png"});
            chrome.browserAction.setBadgeText({text:"SSL"});
            console.log("SSL found,"+currentURL+" redirected to"+httpsURL);
        } else {
            //donothing
            console.log(currentURL+" has no SSL");
            chrome.browserAction.setIcon({path:"../images/padlock_red.png"});
        }
    });
}

阿贾克斯调用:

function checkSSL(url){
    $.support.ajax = true;
    $.ajax({
        url: url,
        type:'HEAD',
        error: function()
        {
            return false;
        },
        success: function()
        {
            return true;
        }
    });
}

问题是,我在控制台中收到以下错误消息:

XMLHttpRequest cannot load https://www.facebook.com/. Origin chrome-extension://pgidanbjmliilmmohlphbagcapafjjpg is not allowed by Access-Control-Allow-Origin.

我不知道可能是什么问题:(

4

2 回答 2

1

您的代码有几个小问题:

  • 您的清单文件仅请求 的权限http://*/*而不是 https://*/*,因此您对 HTTPS 站点的请求失败。您需要获得许可,因此您可以通过所有协议*://*/*获取所有域上的所有页面,而不仅仅是通过 HTTP。

  • 第二个问题是您希望您的$.ajax调用返回一个布尔值,但事实并非如此。该$.ajax调用有两个回调,每个回调都返回一个布尔值,但checkSSL在 Ajax 调用完成之前终止,这意味着checkSSL总是返回undefined

你想要做的是提供checkSSL一个回调函数作为参数:

function checkSSL(url, callback){
    $.ajax({
        url: url,
        type:'HEAD',
        error: function() { callback(false); },
        success: function() { callback(true); }
    });
}

然后,在调用后使用该回调运行调用代码checkSSL

function redirect() {    
    chrome.tabs.query({active: true}, function(tabArray) {  
        var currentURL = tabArray[0].url;               //http://facebook.com
        var httpsURL = generateSSL(currentURL);         //https://facebook.com
        if(httpsURL == currentURL){
            console.log(currentURL+" is already on HTTPS");
            chrome.browserAction.setIcon({path:"../images/padlock_green.png"});
        } else {
            // call checkSSL and take action in an anonymous callback function!
            checkSSL(httpsURL, function(urlDoesExist) { 
                if(urlDoesExist) {                 
                    chrome.tabs.update(tabArray[0].id, {url: httpsURL});
                    chrome.browserAction.setIcon({path:"../images/padlock_green.png"});
                    chrome.browserAction.setBadgeText({text:"SSL"});
                    console.log("SSL found,"+currentURL+" redirected to"+httpsURL);
                } else {
                    //donothing
                    console.log(currentURL+" has no SSL");
                    chrome.browserAction.setIcon({path:"../images/padlock_red.png"});
                }
            });
        }
    });
}

Notice the changes to the code below the first else. We can't decide what to do until the Ajax call has resolved, so we have the Ajax success and error functions fire a callback with a boolean argument. That callback function then takes action based on the value of the boolean.

于 2012-04-17T14:17:24.547 回答
0

如果您打包您的扩展,您可以进行跨域请求,但如果您将其创建为托管应用程序/扩展,则不允许,请参阅:

Chrome 扩展跨域请求

于 2012-04-16T12:24:33.093 回答