实现一个 Chrome 浏览器插件,用于自动填充账号密码并点击登录按钮

1,116 阅读7分钟

要实现一个 Chrome 浏览器插件,用于自动填充账号密码并点击登录按钮,可以通过以下步骤完成:

1. 创建 Chrome 插件的基本结构

Chrome 插件通常包含以下文件:

  • manifest.json:插件的配置文件。
  • popup.htmlpopup.js:用于定义插件的弹出界面和逻辑。
  • content.js:用于与网页内容交互的脚本。
  • background.js(可选):用于处理后台逻辑。

2. 定义 manifest.json

manifest.json 是插件的核心配置文件,定义了插件的基本信息和权限。

JSON复制

{
  "manifest_version": 3,
  "name": "Auto Login Plugin",
  "version": "1.0",
  "description": "Automatically fill in credentials and login",
  "permissions": [
    "activeTab",
    "storage",
    "scripting"
  ],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "images/icon16.png",
      "48": "images/icon48.png",
      "128": "images/icon128.png"
    }
  },
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ],
  "icons": {
    "16": "images/icon16.png",
    "48": "images/icon48.png",
    "128": "images/icon128.png"
  }
}

3. 创建 popup.htmlpopup.js

popup.html 是插件弹出界面的 HTML 文件,popup.js 是对应的逻辑脚本。

popup.html

HTML复制

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Auto Login</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      padding: 10px;
    }
    button {
      margin: 5px;
    }
  </style>
</head>
<body>
  <h3>Choose Account</h3>
  <button id="user1">Account 1</button>
  <button id="user2">Account 2</button>
  <script src="popup.js"></script>
</body>
</html>

popup.js

JavaScript复制

document.getElementById('user1').addEventListener('click', () => {
  const credentials = { username: 'user1', password: 'password1' };
  chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
    chrome.tabs.sendMessage(tabs[0].id, { action: 'fillCredentials', credentials });
  });
});

document.getElementById('user2').addEventListener('click', () => {
  const credentials = { username: 'user2', password: 'password2' };
  chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
    chrome.tabs.sendMessage(tabs[0].id, { action: 'fillCredentials', credentials });
  });
});

4. 创建 content.js

content.js 是用于与网页内容交互的脚本,负责填充账号密码并点击登录按钮。

JavaScript复制

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'fillCredentials') {
    const { username, password } = request.credentials;

    // 填充账号和密码
    document.querySelector('input[placeholder="Username"]').value = username;
    document.querySelector('input[placeholder="Password"]').value = password;

    // 点击登录按钮
    document.querySelector('button[type="submit"]').click();
  }
});

5. 适配 Ant Design 的 Input 和 Button

由于登录页面使用了 Ant Design 的 InputButton 组件,content.js 中的 DOM 选择器需要根据实际页面结构进行调整。

例如:

  • 如果用户名输入框的 placeholder 是 "Username",密码输入框的 placeholder 是 "Password",登录按钮的 type 是 "submit",则上述代码可以直接使用。
  • 如果页面结构复杂,可以通过 classid 定位输入框和按钮。

6. 测试插件

  1. 打开 Chrome 浏览器,进入 chrome://extensions/
  2. 启用“开发者模式”,点击“加载已解压的扩展程序”,选择插件目录。
  3. 打开目标登录页面,点击插件图标,选择账号进行测试。

通过以上步骤,你可以实现一个 Chrome 插件,自动填充账号密码并点击登录按钮。

在 React 开发的界面中,直接通过 DOM 操作(如 element.value = '...')修改 input 的值通常是无效的,因为 React 使用了虚拟 DOM 和受控组件来管理输入框的值。React 的输入框值是由组件状态(如 useState)控制的,而不是直接通过 DOM 操作修改的。

解决方案:使用 React 的事件触发机制

为了在 Chrome 插件中正确地填充 React 的输入框,你需要模拟用户输入事件,而不是直接修改 DOM 的 value 属性。以下是实现方法:


1. 修改 content.js:模拟用户输入事件

content.js 中,使用 dispatchEvent 来模拟用户输入事件,这样可以触发 React 的状态更新。

JavaScript复制

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'fillCredentials') {
    const { username, password } = request.credentials;

    // 获取用户名输入框
    const usernameInput = document.querySelector('input[placeholder="Username"]');
    // 获取密码输入框
    const passwordInput = document.querySelector('input[placeholder="Password"]');
    // 获取登录按钮
    const loginButton = document.querySelector('button[type="submit"]');

    // 模拟输入事件
    const simulateInput = (element, value) => {
      element.value = value; // 设置值
      const event = new Event('input', { bubbles: true }); // 创建 input 事件
      Object.defineProperty(event, 'target', { writable: false, value: element }); // 设置事件目标
      element.dispatchEvent(event); // 触发事件
    };

    // 填充用户名和密码
    simulateInput(usernameInput, username);
    simulateInput(passwordInput, password);

    // 点击登录按钮
    loginButton.click();
  }
});

2. 确保选择器正确

由于 React 的 InputButton 组件可能使用了 Ant Design 或其他库,你需要确保选择器能够正确匹配到目标元素。可以通过以下方式定位:

  • 使用 placeholder 属性(如 input[placeholder="Username"])。
  • 使用 classid(如果页面有明确的标识符)。
  • 如果页面结构复杂,可以使用开发者工具(F12)检查元素的属性。

3. 测试插件

  1. 打开 Chrome 浏览器,进入 chrome://extensions/
  2. 启用“开发者模式”,点击“加载已解压的扩展程序”,选择插件目录。
  3. 打开目标 React 登录页面,点击插件图标,选择账号进行测试。

注意事项

  1. 动态选择器:如果页面的 DOM 结构动态变化(例如,输入框的 classid 是动态生成的),你可能需要更复杂的逻辑来定位输入框。可以尝试使用更通用的选择器(如 input[type="text"]input[type="password"])。
  2. 事件兼容性:在某些情况下,React 可能需要更复杂的事件处理(如 onChangeonKeyDown)。如果 input 事件不起作用,可以尝试触发 change 事件。
  3. 安全性:自动填充密码可能会带来安全风险,确保插件仅在可信的网站上运行,并且用户明确授权。

通过上述方法,你可以实现一个 Chrome 插件,能够正确地在 React 开发的登录页面中自动填充账号和密码。

这段代码的核心作用是通过模拟用户输入事件来更新 React 中的受控组件(如 input)的值。在 React 中,input 组件通常是受控的,其值由组件的状态(如 useState)管理,而不是直接通过 DOM 的 value 属性设置。因此,直接修改 inputvalue 属性通常不会触发 React 的状态更新,也就无法正确更新界面。

为了在 Chrome 插件中实现对 React 界面的 input 框赋值,需要模拟一个用户输入事件(如 inputchange 事件),这样可以触发 React 的状态更新机制。以下是代码的详细解释:


代码解析

JavaScript复制

const simulateInput = (element, value) => {
  element.value = value; // 设置值
  const event = new Event('input', { bubbles: true }); // 创建 input 事件
  Object.defineProperty(event, 'target', { writable: false, value: element }); // 设置事件目标
  element.dispatchEvent(event); // 触发事件
};

1. 设置值:element.value = value;

  • 这一步直接修改了 DOM 元素的 value 属性。虽然这不会触发 React 的状态更新,但它为后续的事件触发提供了正确的值。

2. 创建事件:const event = new Event('input', { bubbles: true });

  • 这里创建了一个 input 事件,bubbles: true 表示事件会冒泡,即从目标元素向上冒泡到父元素。
  • 在 React 中,事件处理通常依赖于事件冒泡机制,因此设置 bubbles: true 是必要的。

3. 设置事件目标:Object.defineProperty(event, 'target', { writable: false, value: element });

  • 这一步通过 Object.defineProperty 修改了事件的 target 属性,将其指向当前的 input 元素。
  • 在 React 的事件处理中,事件的 target 属性会被用来获取事件的来源元素。通过显式设置 target,可以确保 React 能够正确识别事件的来源。

4. 触发事件:element.dispatchEvent(event);

  • 使用 dispatchEvent 方法将创建的事件派发到目标元素上。
  • 这一步会触发 React 的事件监听器,从而触发状态更新逻辑,最终更新 input 的值。

为什么这段代码能够给 React 界面的 input 赋值?

在 React 中,受控组件的值是由组件状态管理的,而不是直接通过 DOM 操作设置的。React 的事件系统会监听 inputchange 事件,并根据事件的 target.value 更新状态。

通过模拟一个 input 事件,并确保事件的 target 指向正确的 input 元素,这段代码能够触发 React 的事件处理逻辑,从而更新组件状态。最终,React 会根据新的状态重新渲染组件,从而更新 input 的值。


注意事项

  1. 事件类型的选择

    • 如果 input 事件不起作用,可以尝试使用 change 事件,因为某些 React 组件可能只监听 change 事件。
  2. 动态选择器

    • 如果页面的 DOM 结构复杂或动态生成,需要确保选择器能够正确匹配到目标元素。
  3. 安全性

    • 自动填充密码可能会带来安全风险,确保插件仅在可信的网站上运行,并且用户明确授权。
  4. 兼容性

    • 在某些情况下,可能需要额外的事件属性(如 currentTargettype)来确保兼容性。

通过这种方式,Chrome 插件可以有效地与 React 开发的界面交互,实现自动填充账号和密码的功能。