1

我正在开发一些使用https服务器的 Node.js 应用程序。在开发它们时,我localhost使用自签名证书运行它们。基本上,一切正常,但我有两个问题:

  1. 当我https://localhost:3000第一次将浏览器指向时,它会警告我有关不受信任的证书。这当然是正确的(而且很重要),但在开发过程中它很烦人。当然,我可以将证书添加为受信任的证书,但它们会不时更改,我不想弄乱证书存储。

  2. 有时我只是忘记https在地址栏中输入该部分,因此 Chrome 尝试使用http. 无论出于何种原因,Chrome 都没有意识到没有网络服务器响应http请求,而是加载、加载、加载……</p>

为了解决这两个问题,我想做的是创建一个位于地址栏旁边的 Chrome 扩展程序,并提供一个按钮,您可以使用该按钮切换其状态:

  • 如果扩展被禁用,它什么也不做。
  • 如果启用了扩展,并且您向localhost(并且只有那时!)发送请求,它将做两件事:
    1. 如果请求使用http,但几秒钟后页面仍然存在pending,则应尝试使用https
    2. 暂时接受任何证书,不管它是否被浏览器信任。

明确地说:这些规则仅适用于localhost.

所以,现在我的问题是:

  • 使用 Chrome 扩展程序可以实现这样的事情吗?
  • 由于我在编写 Chrome 扩展程序方面的经验绝对为零,所以一个好的起点是什么,我应该在 Google 上寻找哪些术语?
4

1 回答 1

5

Google Chrome 扩展文档是一个很好的起点。您描述的所有内容都可以使用 Chrome 扩展程序,除了“证书接受”部分。(我并不是说这不可能,我只是不知道是不是——但如果是的话,我会非常惊讶(和担心)。)

当然,--ignore-certificate-errors命令行开关总是有的,但它不会localhost和其他域区分开来。

如果您决定实现其余功能,我建议您先查看chrome.tabs和/或chrome.webRequest。(让我也提一下“内容脚本”不太可能有任何用处。)


也就是说,下面是一些演示扩展的代码(只是为了让你开始)。

作用:
禁用时 -> 无
激活时 -> 侦听选项卡被定向到类似 URLhttp://localhost[:PORT][/...]并将它们重定向到https(它不等待响应或任何东西,它只是立即重定向它们)。

如何使用:
单击浏览器操作图标以激活/停用。

当然,它并不完美/完整,但它是一个起点:)


扩展目录结构:

        extention-root-directory/
         |_____ manifest.json
         |_____ background.js
         |_____ img/
                 |_____ icon19.png
                 |_____ icon38.png

manifest.json:(
有关可能字段的更多信息, 请参见此处。)

{
    "manifest_version": 2,
    "name":    "Test Extension",
    "version": "0.0",
    "default_locale": "en",
    "offline_enabled": true,
    "incognito":       "split",

    // The background-page will listen for
    // and handle various types of events
    "background": {
        "persistent": false,   // <-- if you use chrome.webRequest, 'true' is required
        "scripts": [
            "background.js"
        ]
    },

    // Will place a button next to the address-bar
    // Click to enable/disable the extension (see 'background.js')
    "browser_action": {
        "default_title": "Test Extension"
        //"default_icon": {
        //    "19": "img/icon19.png",
        //    "38": "img/icon38.png"
        //},
    },

    "permissions": [
        "tabs",                  // <-- let me manipulating tab URLs
        "http://localhost:*/*"   // <-- let me manipulate tabs with such URLs 
    ]
}

background.js:(
相关文档:背景页面事件页面浏览器操作chrome.tabs API

/* Configuration for the Badge to indicate "ENABLED" state */
var enabledBadgeSpec = {
    text: " ON ",
    color: [0, 255, 0, 255]
};
/* Configuration for the Badge to indicate "DISABLED" state */
var disabledBadgeSpec = {
    text: "OFF",
    color: [255, 0, 0, 100]
};


/* Return whether the extension is currently enabled or not */
function isEnabled() {
    var active = localStorage.getItem("active");
    return (active && (active == "true")) ? true : false;
}

/* Store the current state (enabled/disabled) of the extension
 * (This is necessary because non-persistent background pages (event-pages)
 *  do not persist variable values in 'window') */
function storeEnabled(enabled) {
    localStorage.setItem("active", (enabled) ? "true" : "false");
}

/* Set the state (enabled/disabled) of the extension */
function setState(enabled) {
    var badgeSpec = (enabled) ? enabledBadgeSpec : disabledBadgeSpec;
    var ba = chrome.browserAction;
    ba.setBadgeText({ text: badgeSpec.text });
    ba.setBadgeBackgroundColor({ color: badgeSpec.color });
    storeEnabled(enabled);
    if (enabled) {
        chrome.tabs.onUpdated.addListener(localhostListener);
        console.log("Activated... :)");
    } else {
        chrome.tabs.onUpdated.removeListener(localhostListener);
        console.log("Deactivated... :(");
    }
}

/* When the URL of a tab is updated, check if the domain is 'localhost'
 * and redirect 'http' to 'https' */
var regex = /^http(:\/\/localhost(?::[0-9]+)?(?:\/.*)?)$/i;
function localhostListener(tabId, info, tab) {
    if (info.url && regex.test(info.url)) {
        var newURL = info.url.replace(regex, "https$1");
        chrome.tabs.update(tabId, { url: newURL });
        console.log("Tab " + tabId + " is being redirected to: " + newURL);
    }
}

/* Listen for 'browserAction.onClicked' events and toggle the state  */
chrome.browserAction.onClicked.addListener(function() {
    setState(!isEnabled());
});

/* Initially setting the extension's state (upon load) */
setState(isEnabled());
于 2013-10-31T12:34:02.823 回答