关于javascript:7分钟学会写一个浏览器插件突破某SDN未登录禁止复制的限制

5次阅读

共计 8289 个字符,预计需要花费 21 分钟才能阅读完成。

  严格意义上说,本篇文章要探讨的应该是“Chrome 扩大(Extension)”而不是“Chrome 插件(Plugins)”,大家无妨先思考一个问题:“浏览器插件”和“浏览器扩大”之间有什么区别?如果您对此感到腻烦,无妨间接跳过此大节的浏览。

对于 Chrome 插件与扩大的误区

  Chrome 浏览器自 2008 年诞生以来产生了很多事件,它是目前性能最齐备、对新个性反对最充沛的 Web 浏览器,Chrome 的呈现,在某种意义上扩大了咱们对浏览器性能的定义,并且它反对第三方开发人员制作的应用程序、插件和扩大。然而这三者有什么区别呢?如果你想取得广告拦截器,那是应用程序还是扩大程序?在 HTML5 之前曾红极一时、能够让网站内容变得更丰盛、带来了视频 / 动画 / 游戏却因平安问题始终饱受诟病的 Adobe Flash,是属于浏览器扩大还是插件?

  在此,咱们先来理解一下 Chrome 应用程序、插件和扩大程序之间(Chrome apps, plugins and extensions)的区别,以便你可能始终晓得本人须要的是什么。

Chrome 应用程序(Chrome Apps)

  Chrome 应用程序的概念,可能是 Chrome 应用程序、插件和扩大程序中最含糊的,因为其实 Google 自身能够调换地指代应用程序和扩大程序。想要证实这一点也不难,你能够转到 Chrome 网上利用店中的扩大程序页面(https://chrome.google.com/webstore/category/extensions),在地址栏中将“extensions”一词替换为“apps”,它实际上会重定向回扩大(extensions)页面!

  Web Store 已经有一个专门的“应用程序(Apps)”局部,在那里提供独立的桌面应用程序。但在 2017 年底,谷歌移除了这些传统的 Chrome 应用程序,因为 Google 推动了“渐进式网络应用程序(Progressive Web Apps,即 PWA)”的构想,从实质上将网站转变为从桌面或手机即时拜访的应用程序,所以现在的搜寻框下方只有“Extensions”和“Themes”两局部了。

  对于一般的 PC 用户来说,Chrome 应用程序现在已融入扩大程序中。如果你正在为 Chrome 寻找广告拦截器、Web Clipper 等,无论你搜寻“Chrome app”还是“Chrome extension”,您最终都会失去一个扩大程序。

Chrome 扩大程序(Chrome Extensions)

  Chrome 扩大程序是 Chrome 的附加组件,旨在 以各种形式改善您的体验。这种体验的改善能够从数据保护程序到广告拦截器,再到让你在 Chrome 中双击单词并立刻理解其含意的字典。您能够在 Chrome 网上利用店中找到扩大程序,当您装置一个扩大程序时,它会在 Chrome 浏览器的右上角显示一个小图标。

  扩大程序能够减少浏览器自身的性能,也 能够调用浏览器的 API,并且同一个浏览器的扩大个别也都是能够 跨操作系统 应用的。比方,你在 Windows 应用的那些 Chrome 扩大,换到 Mac 平台上也一样能用。

  扩大为浏览器增加个性与性能,它个别通过 web 技术——HTML,CSS 还有 JavaScript 来创立。扩大其实是一个压缩文件,Firefox 的扩大是.xpi、Chrome 扩大格局为.crx

Chrome 插件(Chrome Plugins)

  插件最好被形容为 “插入”Chrome 的代码包,容许 Web 开发人员将某些性能、动画、视频等嵌入到他们的网站中,插件 可调用操作系统的 API,并且不同操作系统的插件个别不能混用,插件次要用于实现浏览器无奈独立实现的性能。

  也就是说,插件使得别的程序能力解决的内容在浏览器的页面中得以展示和解决。所以插件个别实现的都是比拟底层的性能,一旦呈现问题,往往就会牵涉到整个操作系统,像 Flash 插件就属于常常被扒出高危破绽的那一类。在 Chrome 57 版本之前,你能够在地址栏中的 chrome://plugins 中查看 Chrome 的所有插件列表,其中包含 Adob​​e Flash Player、Chrome PDF Viewer 和 Java 插件等,当初 chrome://chrome-urls/ 中曾经找不到 chrome://plugins 了。

  chrome://plugins不再存在的局部起因是出于平安思考,Chrome 不再反对 NPAPI 插件——一些插件不再工作,而其余插件已以各种形式集成到 Chrome 中。例如,基于 Java 的小程序不再在浏览器中运行,PDF 查看器等性能已间接集成到浏览器中。因而,有点像应用程序(Chrome Apps),Chrome 插件的也正在逐渐淘汰或集成到浏览器的主体中。

  插件的格局通常是 二进制文件 ,如 windows 下的插件个别是dll,linux 下的插件个别是os 格局。

  从实质上讲,“Chrome 应用程序”会被 PWA 所代替,而这些年来插件基本上已被弃用,所以你在 Chrome 中惟一须要关怀的就是扩大程序。

  真正意义上的 Chrome 插件是更底层的浏览器性能扩大,然而浏览器插件和扩大这两个概念早已被混同。鉴于大部分人对 Chrome 插件的叫法曾经习惯,本文也全副采纳这种叫法,但您应该晓得,本文所形容的 Chrome 插件实际上指的是 Chrome 扩大

顺便简略做个补充,除了以上提到的 3 个概念,你可能还看到过ActiveX(控件)、Addon 等概念,其实 ActiveX 是 IE 内核浏览器下的插件(Plugin),随着 IE 浏览器从 Windows 11 中隐没,并将在 2022 年正式退出历史舞台,咱们无需过多关注;Addon 是属于 Mozilla 系浏览器的,中文名字叫附加组件,其实和浏览器扩大是同一类利用。

浏览器插件的外围元素

manifest.json

  一个 Chrome 扩大其实就是一个配置(入口)文件 manifest.json 和一系列 html、css、js、图片文件的汇合,扩大 / 插件从它们的 manifest.json 开始,所以 manifest.json 是一个Chrome 插件最重要也是必不可少的文件,用来配置所有和插件相干的配置,必须放在根目录。个别至多应该蕴含上面这些配置:

// manifest.json
{
  "name": "Getting Started Example", // 扩大的名称(name)"version": "1.0", // 插件版本号
  "description": "Build an Extension!", // 插件形容
  "manifest_version": 2, // manifest 版本,目前是必须是 2 或者 3

  // 指定扩大在 Chrome 工具栏中的图标,它定义了扩大图标文件地位(default_icon)、// 悬浮提醒(default_title)和点击扩大图标所显示的页面地位(default_popup)"browser_action": {
    "default_title": "Hello, 某 SDN!",
    "default_icon": "/images/logo.png", // 浏览器右上角图标设置
    "default_popup": "popup.html"
  }
}

当然,一个 manifest.json 文件能够蕴含很多货色,能够参考 Manifest file format,后续应用到其余配置会在正文中进行阐明。

VSCode 在书写.json 文件的备注时标红提醒 Comments are not permitted in JSON.(521),此时只需点击 VSCode 界面右下角的“JSON”,在顶部展现出的框中输出“JSON with Comments”,点击应用即可解决。

popup.html

  这个名称不是固定的,取决于 manifest.json中对 browser_action 的“default_popup”字段的配置,它定义了点击插件的图标所展现的弹窗页面 HTML,popup.html像一般 html 一样能够间接引入其余 js 文件。须要留神的一点是,这外面引入的 js,如果间接操作 DOM,操作的是 popup.html 产生的 DOM,而不是浏览器以后展现页面的 DOM。

content_scripts

  这一项来自于 manifest.jsoncontent_scripts配置项,申明了 须要间接注入页面的 JS,这里的 JS 能够间接操作以后页面的 DOM 对象,所以这个文件在须要对关上的页面进行操作时会很有用。

开发调试

  Chrome 插件没有严格的我的项目构造要求,只有保障根目录有一个 manifest.json 即可,也不须要专门的 IDE 进行开发。

  开发调试时,进入插件治理页面最简洁的形式是在地址栏输出 chrome://extensions/ 进行拜访。其余两种进入插件治理页面的形式如下图所示:

  关上右上角 开发者模式 便能够文件夹的模式间接加载插件,否则只能装置.crx 格局的文件。默认状况下,Chrome 要求插件必须从它的 Chrome 利用商店装置,其它任何网站下载的以及本人打包的都无奈间接装置。所以,其实咱们能够把 crx 文件解压,而后通过开发者模式间接加载。

  开发过程中,代码有任何改变都必须从新加载插件,点击对应插件的从新加载按钮或者刷新以后插件治理页面均可。如果呈现谬误,将会呈现相似上面的界面,更改后,你须要先点击“谬误”按钮进入弹窗对谬误进行革除。

开发过程中遇到的更多细节能够参考官网 Debugging extensions 文档。

3 分钟写一个浏览器插件,解决某 SDN 未登录无奈复制代码的问题

  咱们晓得,前段时间某 SDN 更新后,未登录时,无奈复制文章中的代码,给开发者带来肯定不便。明天咱们就花 3 分钟工夫写一个浏览器插件,冲破这种限度。

  基本思路其实很简略,通过将以后页面的 document.body.contentEditable 值设置为 true 来达到可复制的成果。当然,这个咱们通过控制台面板或者“自定义书签“的形式也能轻松实现,这里只是让大家体验一下简略插件的开发,防止出手就是”Hello World!“,😄

书签性能的实现可参考前端装逼技巧 108 式(一)—— 打工人。

  上面将逐渐介绍我的项目各文件相干信息,您也能够间接点击这里在线查看残缺代码。整个我的项目 外围代码有余 30 行,置信您能藉此迅速入门 Chrome 插件开发,激发趣味和潜能,写出更有用的插件或者利用。

目录构造

  目录结构图:

  目录解释:

  • images

    • logo.png:插件图标。
  • js

    • popup.js:弹窗 popup.html 中应用的 js;
    • content_script.js:须要间接注入页面的 js;
  • manifest.json:配置文件,插件开发中的必备项;
  • popup.html:插件弹窗;
  • style.css:弹窗款式文件;

manifest.json 配置文件

{
  // 清单文件的版本,必须是 2 或者 3,// 文档见 https://developer.chrome.com/docs/extensions/mv3/manifest/manifest_version/
  "manifest_version": 2,
  // 插件的名称
  "name": "Copy SDN",
  // 插件的版本
  "version": "1.0.0",
  // 插件形容
  "description": "不登录仍然能够在某 SDN 页面进行代码复制!",
  // 指定扩大在 Chrome 工具栏中的图标,它定义了扩大图标文件地位(default_icon)、// 悬浮提醒(default_title)和点击扩大图标所显示的页面地位(default_popup)"browser_action": {
    "default_title": "Hello, 某 SDN!",
    "default_icon": "/images/logo.png", // 浏览器右上角图标设置
    "default_popup": "popup.html"
  },
  // https://developer.chrome.com/docs/extensions/mv2/manifest/icons/
  // 128x128 的图标;它在装置期间和 Chrome 网上利用店应用
  // 48x48 图标,用于扩大程序管理页面 (chrome://extensions)
  // 16x16 图标用作扩大页面的收藏夹图标
  // 这里只写一个其实也是能够的
  "icons": {"128": "/images/logo.png"},
  // 须要间接注入页面的 JS
  "content_scripts": [
    {//"matches": ["http://*/*", "https://*/*"],"<all_urls>" 示意匹配所有地址
      "matches": ["https://blog.csdn.net/*"],
      // 多个 JS 按程序注入
      "js": ["/js/content_script.js"],
      // "css": ["css/custom.css"],
      // 代码注入的工夫,可选值:"document_start", "document_end", or "document_idle",// document_idle 示意页面闲暇时,为默认值
      "run_at": "document_start"
    }
  ],
  // 定义了扩大须要向 Chrome 申请的权限,比方通过 XMLHttpRequest 跨域申请数据、拜访浏览器选项卡(tabs)// 获取以后流动选项卡(activeTab)、浏览器告诉(notifications)、存储(storage)等,能够依据须要增加。"permissions": ["tabs"]
}

popup.html 和 css 制作插件弹窗

popup.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./style.css" />
    <title>Copy SDN</title>
  </head>

  <body>
    容许复制 Code:<input type="checkbox" class="switch" id="toggle" />
    <!-- 这里引入了 popup.js,来给 popup 弹窗增加一些交互性能 -->
    <script src="./js/popup.js"></script>
  </body>
</html>

弹窗款式文件style.css

body {
  width: 160px;
  height: 24px;
  background-color: lavender;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Switch 开关款式 */
input[type='checkbox'].switch {
  outline: none;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  position: relative;
  width: 40px;
  height: 20px;
  background: #ccc;
  border-radius: 10px;
  transition: border-color 0.3s, background-color 0.3s;
}

input[type='checkbox'].switch::after {
  content: '';
  display: inline-block;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0, 0, 2px, #999;
  transition: 0.4s;
  top: 2px;
  position: absolute;
  left: 2px;
}

input[type='checkbox'].switch:checked {background: rgb(19, 206, 102);
}

/* 当 input[type=checkbox]被选中时:伪元素显示上面款式 地位发生变化 */
input[type='checkbox'].switch:checked::after {
  content: '';
  position: absolute;
  left: 55%;
  top: 2px;
}

  以上代码将构建出如下插件弹窗 UI:

popup.js 给弹窗增加交互

// 这里的 js 其实是操作 popup.html 产生的 dom 的
document.addEventListener('DOMContentLoaded', function () {// 获取开关按钮的初始值。这里 { type: 'get_editable'} 是能够随便定义的,能够传递任何你想传递的信息
  sendMessageToContentScript({type: 'get_editable'}, (response) => {toggle.checked = ['true', true].includes(response) ? 'checked' : null;
  });

  // 切换 contentEditable 状态
  toggle.addEventListener('change', () => {sendMessageToContentScript({ type: 'toggle'});
  });
});

// 向 content_scripts 发送音讯的函数
function sendMessageToContentScript(message, callback) {// 这里用到了 tabs,所以后面配置文件须要配置 "permissions": ["tabs"]
  chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {chrome.tabs.sendMessage(tabs[0].id, message, (response) => {if (callback) callback(response);
    });
  });
}

content_script.js 向页面注入 JS

// 所谓 content-scripts,其实就是 Chrome 插件中向页面注入脚本的一种模式(尽管名为 script,其实还能够包含 css),// 借助 content-scripts 咱们能够实现通过配置的形式轻松向指定页面注入 JS 和 CSS(如果须要动静注入,能够参考下文),// 最常见的比方:广告屏蔽、页面 CSS 定制,等等。// 接管音讯
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  // 数据处理和返回。是不是有点相似 redux 中 reducer 数据处理的感觉
  switch (request.type) {
    case 'get_editable':
      // 将以后文档是否可编辑的信息返回给 popup,管制开关的状态
      sendResponse(document.body.contentEditable);
      break;
    case 'toggle':
      // 切换可编辑状态
      document.body.contentEditable = ![true, 'true'].includes(document.body.contentEditable);
    default:
      break;
  }
});

打包与公布

  在插件治理页左上角有一个“打包扩大程序”的按钮,点击就会呈现如下界面,抉择要打包的文件夹进行打包即可,你会失去一个 .crx 的压缩文件,这个实际上就是你常常装置插件时装置的压缩包文件。


  要公布到 Google 利用商店的话,须要先领取 5 美元的注册费成为开发者:Register as a Chrome Web Store Developer。

参考资料

  • How to Build & Publish a Chrome Extension in 13 Minutes?🔥
  • Chrome Apps, Plugins, Extensions: What’s the Difference?
  • 【干货】Chrome 插件 (扩大) 开发全攻略

  本文首发于集体博客,欢送斧正和 star。

正文完
 0