使用谷歌扩展API实现脚本触发人为点击事件

前言


我想实现一个功能,就是在网页上达到某个条件时自动点击一个按钮。但是我发现网站会检测点击事件是否是人为的,如果不是,就会报错刷新页面。我查了一下,发现点击事件有一个isTrusted的只读属性,人为点击时为true,脚本触发点击时为false。那么如何用脚本触发一个isTrusted = true的点击事件呢?

使用谷歌扩展API

如何触发'isTrusted = true'点击事件_An_s的博客-CSDN博客

我参考了这篇文章,知道了可以通过编写谷歌扩展来实现isTrusted = true的点击事件。谷歌扩展有一个debuggerAPI,可以让扩展程序调试目标网页,并发送各种命令给它。其中有一个命令是Input.dispatchMouseEvent,可以用来模拟鼠标事件。这个命令可以设置鼠标事件的类型、位置、按钮等参数,并且可以让事件的isTrusted属性为true

假设目标网站有两个按钮,如果使用脚本点击btn1会打印false,现在我们要实现在点击btn2的事件里触发btn1的点击且打印event.isTrustedtrue

html 复制代码
<body>
  <button id="btn1">btn1</button>
  <button id="btn2">btn2</button>
  <script>
    const btn1 = document.querySelector('#btn1')
    btn1.addEventListener('click', (event) => {
      console.log(event.isTrusted)
    })
    btn1.click() // => false
  </script>
</body>

现在编写谷歌扩展,根目录下有三个文件manifest.jsoncontent.jsbackground.js

manifest.json

json 复制代码
{
  "manifest_version": 3,
  "name": "Click Button",
  "version": "1.0",
  "description": "A browser extension that clicks a button using chrome.debugger",
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["https://www.baidu.com/*"], // 匹配的目标网站
      "js": ["content.js"]
    }
  ],
  "permissions": ["debugger"]
}

这个文件是谷歌扩展的配置文件,主要说明了扩展的基本信息、后台服务、内容脚本和权限等。

content.js

js 复制代码
const btn1 = document.querySelector('#btn1')
const btn2 = document.querySelector('#btn2')
btn2.addEventListener('click', () => {
  const rect = btn1.getBoundingClientRect()
  const x = rect.left + rect.width / 2
  const y = rect.top + rect.height / 2
  chrome.runtime.sendMessage({ x, y })
})

这个文件是内容脚本,它可以直接访问目标网页的DOM元素,并与后台服务通信。这里我们给btn2添加了一个点击事件,当点击btn2时,就会获取btn1的位置,并把它发送给后台服务。

background.js

js 复制代码
const sendMouseEvent = async ({ tabId, type, x, y }) => {
  await chrome.debugger.sendCommand({ tabId }, 'Input.dispatchMouseEvent', {
    type,
    x,
    y,
    button: 'left',
    clickCount: 1 // 这个参数很重要,表示点击次数,如果不设置或者为0,则无法触发点击事件
  })
}

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  const tabId = sender.tab.id // 这里我们用sender.tab.id来获取目标网页的ID,这是一种简单的方法,不需要额外的权限
  const { x, y } = request
  chrome.debugger.attach({ tabId }, '1.2', async () => {
    await sendMouseEvent({ tabId, type: 'mousePressed', x, y })
    await sendMouseEvent({ tabId, type: 'mouseReleased', x, y })
    await chrome.debugger.detach({ tabId })
  })
})

这个文件是后台服务,它可以在后台运行一些逻辑,并与内容脚本通信。这里我们定义了一个函数sendMouseEvent,用来发送鼠标事件给目标网页。然后我们监听内容脚本发送的消息,获取到btn1的位置,然后用chrome.debugger.attach方法连接到目标网页,并调用sendMouseEvent函数模拟点击btn1,最后用chrome.debugger.detach方法断开连接。

在浏览器扩展里打开开发人员模式,就可以通过加载解压缩的扩展把这个目录添加为一个扩展了。

以上就实现了使用脚本触发isTrusted = true的点击事件。

总结

  • 在这个过程中,我学习了如何编写谷歌扩展,并使用了一些有用的API,如debuggerInput.dispatchMouseEvent
  • 我遇到了一些问题,比如如何获取目标网页的ID,以及如何设置鼠标事件的参数。我通过查阅文档和参考其他人的教程,找到了解决方法。
  • 我觉得这个功能很有趣,也很实用,可以用来自动化一些网页操作。我想以后还可以尝试更多的功能和技巧。

参考链接

相关推荐
中微子1 小时前
React状态管理最佳实践
前端
烛阴1 小时前
void 0 的奥秘:解锁 JavaScript 中 undefined 的正确打开方式
前端·javascript
中微子1 小时前
JavaScript 事件与 React 合成事件完全指南:从入门到精通
前端
Hexene...1 小时前
【前端Vue】如何实现echarts图表根据父元素宽度自适应大小
前端·vue.js·echarts
初遇你时动了情1 小时前
腾讯地图 vue3 使用 封装 地图组件
javascript·vue.js·腾讯地图
dssxyz1 小时前
uniapp打包微信小程序主包过大问题_uniapp 微信小程序时主包太大和vendor.js过大
javascript·微信小程序·uni-app
天天扭码2 小时前
《很全面的前端面试题》——HTML篇
前端·面试·html
xw52 小时前
我犯了错,我于是为我的uni-app项目引入环境标志
前端·uni-app
!win !2 小时前
被老板怼后,我为uni-app项目引入环境标志
前端·小程序·uni-app
Burt2 小时前
tsdown vs tsup, 豆包回答一坨屎,还是google AI厉害
前端