您的位置:首页 > 房产 > 建筑 > 运营一个网站的成本_外墙清洗_怎么做外链_培训机构哪家最好

运营一个网站的成本_外墙清洗_怎么做外链_培训机构哪家最好

2025/1/10 18:36:02 来源:https://blog.csdn.net/qq_42727752/article/details/145043570  浏览:    关键词:运营一个网站的成本_外墙清洗_怎么做外链_培训机构哪家最好
运营一个网站的成本_外墙清洗_怎么做外链_培训机构哪家最好

浏览器网络插件

  • 🌐 浏览器网络代理插件
    • 0️⃣ 前言
    • 😎 快速体验
    • 🔍 浏览器兼容性
    • 🚀 使用方法
    • 🔨 简单的实现逻辑

🌐 浏览器网络代理插件

0️⃣ 前言

Firefox 浏览器网络设置功能我觉得还是蛮实用的,但是, ChromeEdge 浏览器却没有类似的简便插件或内建选项。我发现浏览器的网络配置接口实际上是存在的, 看着功能实现不难, 简单的做了一个手动配置网络的插件 🔧🌐.


😎 快速体验

👉 项目源码: Browser_Proxy_Plugin

🎉 欢迎一起交流!💬 (⭐️ start 和 🍴 fork,感谢大家的支持!🙏)

在这里插入图片描述


🔍 浏览器兼容性

目前已在以下浏览器中测试,功能完全正常:

  • 🟢 Chrome 131
  • 🟢 Edge 131

其他现代浏览器(如 Firefox 等)理论上也支持,但没有去测试。


🚀 使用方法

  1. 打开 Chrome 设置 ⚙️

    • 点击 Chrome 窗口右上角的 (三个点)。
    • 依次选择 更多工具 > 扩展程序
  2. 启用开发者模式 🧑‍💻

    • 在扩展程序页面右上角,找到 开发者模式 开关,点击将其打开。
  3. 加载解压后的文件夹 📁

    • 点击页面左上角的 加载已解压的扩展程序 按钮。
    • 在弹出的文件选择窗口中,选择刚刚解压的插件文件夹。
  4. 确认加载成功

    • 如果一切正常,插件会立即出现在扩展程序列表中。
    • 你可以在 Chrome 右上角的扩展图标中看到它。

🔨 简单的实现逻辑

  1. HTML 语言写 popup.html 也就是这个弹出的界面的样式

我尝试引入 VUE3ElementPlus 框架 发现不是那么容易 并且容易出错, 后面调查发现用 Bootstrap 是不错的 有机会可以试试.

  1. module/popup.js 里面获取元素的 id 然后做事件的监听和业务的实现, 代码如下
document.addEventListener("DOMContentLoaded", function () {// 默认的bypass列表const defaultBypassList = ["127.0.0.1/8","192.168.1.0/24","::1","localhost",".net.nz",];// 这个插件默认的浏览器存储的数据格式let initialSettings = {bypassList: [],httpPort: "8080",httpProxy: "example.com",httpsPort: "",httpsProxy: "",proxyEnabled: false,socksHost: "",socksPort: "",useForHttps: false,};/** ================== Step 1 ================== */// 得到插件的全部 HTML Elementconst noProxyToggle = document.getElementById("no-proxy-checkbox");const manualProxyToggle = document.getElementById("manual-proxy-checkbox");const proxyConfiguration = document.getElementById("proxy-configuration");const proxyPanel = document.getElementById("proxy-panel");const httpProxyInput = document.getElementById("http-proxy");const httpPortInput = document.getElementById("http-port");const httpsProxyInput = document.getElementById("https-proxy");const httpsPortInput = document.getElementById("https-port");const socksHostInput = document.getElementById("socks-host");const socksPortInput = document.getElementById("socks-port");const bypassListInput = document.getElementById("bypass-list");const useForHttpsCheckbox = document.getElementById("use-for-https");const applyButton = document.getElementById("apply-button");const cancelButton = document.getElementById("cancel-button");/** ================== Step 2 ================== */// 给插件的HTML Element注入监听事件 观察变化// 2.1 不使用代理和使用手动代理的互斥行为noProxyToggle.addEventListener("change", () => {if (noProxyToggle.checked) manualProxyToggle.checked = false;else manualProxyToggle.checked = true;// 主动触发一次使用手动代理的行为促使它去修改样式manualProxyToggle.dispatchEvent(new Event("change"));});manualProxyToggle.addEventListener("change", () => {if (manualProxyToggle.checked) {proxyConfiguration.classList.remove("disabled");proxyPanel.classList.remove("not-allowed");noProxyToggle.checked = false;} else {proxyConfiguration.classList.add("disabled");proxyPanel.classList.add("not-allowed");noProxyToggle.checked = true;}});// 2.2 HTTP 和 HTTPS 如果是共享状态的话需要同步更新数据httpProxyInput.addEventListener("input", () => {if (useForHttpsCheckbox.checked)httpsProxyInput.value = httpProxyInput.value;});httpPortInput.addEventListener("input", () => {if (useForHttpsCheckbox.checked) httpsPortInput.value = httpPortInput.value;});useForHttpsCheckbox.addEventListener("change", () => {if (useForHttpsCheckbox.checked) {httpsProxyInput.classList.add("disabled", "not-allowed");httpsPortInput.classList.add("disabled", "not-allowed");httpsProxyInput.value = httpProxyInput.value;httpsPortInput.value = httpPortInput.value;} else {httpsProxyInput.classList.remove("disabled", "not-allowed");httpsPortInput.classList.remove("disabled", "not-allowed");}});// 2.3 从 HTML Element 上拿出状态写入存储 并且需要立即生效设置applyButton.addEventListener("click", () => {// 获取用户输入并将其分割为数组,同时移除多余的空格const bypassList = bypassListInput.value.split(";").map((url) => url.trim()).filter(Boolean);// 将默认的bypassList加入用户输入的bypassListconst finalBypassList = [...new Set([...defaultBypassList, ...bypassList])];const proxyConfig = {mode: "fixed_servers",rules: {singleProxy: {scheme: "http",host: httpProxyInput.value || "example.com",port: parseInt(httpPortInput.value) || 8080,},// 使用合并后的 bypassListbypassList: finalBypassList,},};// 保存设置到 Chrome 存储中chrome.storage.sync.set({proxyEnabled: manualProxyToggle.checked,httpProxy: httpProxyInput.value,httpPort: httpPortInput.value,httpsProxy: useForHttpsCheckbox.checked? httpProxyInput.value: httpsProxyInput.value,httpsPort: useForHttpsCheckbox.checked? httpPortInput.value: httpsPortInput.value,socksHost: socksHostInput.value,socksPort: socksPortInput.value,// 保存合并后的 bypassListbypassList: finalBypassList,useForHttps: useForHttpsCheckbox.checked,// 保存代理配置proxySettings: proxyConfig,},// 立即应用设置function () {if (manualProxyToggle.checked) {chrome.proxy.settings.set({value: proxyConfig,scope: "regular",},function () {});} else {chrome.proxy.settings.clear({ scope: "regular" }, function () {});}});window.close();});// 2.4 取消设置需要回退回存储中记录的状态cancelButton.addEventListener("click", () => {// 恢复到初始设置if (initialSettings.proxyEnabled)manualProxyToggle.checked = initialSettings.proxyEnabled;if (initialSettings.httpProxy)httpProxyInput.value = initialSettings.httpProxy;if (initialSettings.httpPort)httpPortInput.value = initialSettings.httpPort;if (initialSettings.httpsProxy)httpsProxyInput.value = initialSettings.httpsProxy;if (initialSettings.httpsPort)httpsPortInput.value = initialSettings.httpsPort;if (initialSettings.socksHost)socksHostInput.value = initialSettings.socksHost;if (initialSettings.socksPort)socksPortInput.value = initialSettings.socksPort;const userBypassList = initialSettings.bypassList? initialSettings.bypassList: [];const combinedBypassList = [...new Set([...defaultBypassList, ...userBypassList]),];bypassListInput.value = combinedBypassList.join(", ");if (initialSettings.useForHttps !== undefined)useForHttpsCheckbox.checked = initialSettings.useForHttps;// 关闭 popupwindow.close();});/** ================== Step 3 ================== */// 入口函数 插件初始化的操作chrome.storage.sync.get(["proxyEnabled","httpProxy","httpPort","httpsProxy","httpsPort","socksHost","socksPort","bypassList","useForHttps",],function (result) {initialSettings = result;// 互斥的两个开关选项if (result.proxyEnabled) manualProxyToggle.checked = true;manualProxyToggle.dispatchEvent(new Event("change"));if (result.httpProxy) httpProxyInput.value = result.httpProxy;if (result.httpPort) httpPortInput.value = result.httpPort;if (result.httpsProxy) httpsProxyInput.value = result.httpsProxy;if (result.httpsPort) httpsPortInput.value = result.httpsPort;if (result.socksHost) socksHostInput.value = result.socksHost;if (result.socksPort) socksPortInput.value = result.socksPort;// 合并不显示默认去掉的bypassListconst userBypassList = result.bypassList ? result.bypassList : [];const combinedBypassList = userBypassList.filter((item) => !defaultBypassList.includes(item));bypassListInput.value = combinedBypassList.join("; ");if (result.useForHttps) useForHttpsCheckbox.checked = result.useForHttps;useForHttpsCheckbox.dispatchEvent(new Event("change"));});
});

大概的框图可以这么表示, 一看就明白

在这里插入图片描述


版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com