+
16
-

回答

可以通过创建一个 Chrome 插件,利用其强大的 API 来实现这个功能。核心思路是:

添加右键菜单:当用户右键点击图片或选中文字时,在上下文菜单中显示我们的自定义选项。

捕获数据

对于图片,Chrome 的上下文菜单 API 会直接提供图片的 URL (srcUrl)。

对于文字,我们需要向当前页面注入一个脚本来获取用户选中的文本。

发送数据:在后台脚本中,使用 fetch API 将捕获到的数据以 JSON 格式发送到你本地的 HTTP API。

下面是详细的步骤和代码。

第1步:创建 manifest.json

这是插件的配置文件,定义了插件的基本信息和所需的权限。

{
  "manifest_version": 3,
  "name": "Send to Localhost",
  "version": "1.0",
  "description": "Send selected text or images to a local HTTP API.",
  "permissions": [
    "contextMenus",    // 用于创建右键菜单
    "activeTab",       // 用于获取当前活动标签页的权限
    "scripting"        // 用于向页面注入脚本(获取选中文本)
  ],
  "host_permissions": [
    "http://localhost/*", // 关键:允许插件向 localhost 发起请求
    "https://localhost/*"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html",
    "default_icon": "icon.png"
  },
  "icons": {
    "48": "icon.png"
  }
}

权限解释

contextMenus: 创建和管理右键菜单。

activeTab + scripting: 这对组合是 Manifest V3 中向当前页面临时注入脚本的标准方式,用于获取选中的文字。

host_permissions: 这是最重要的权限。它明确允许你的插件向 http://localhost 或 https://localhost 下的任何端口和路径发起网络请求。没有这个,fetch 请求会被浏览器的安全策略阻止。

第2步:创建后台脚本 background.js

这是插件的核心逻辑所在,负责创建菜单、处理点击事件和发送数据。

// 在插件安装时创建右键菜单
chrome.runtime.onInstalled.addListener(() => {
  // 为选中的文字创建菜单项
  chrome.contextMenus.create({
    id: "send-text",
    title: "发送选中的文字到 Localhost",
    contexts: ["selection"] // 只在用户选中文字时显示
  });

  // 为图片创建菜单项
  chrome.contextMenus.create({
    id: "send-image",
    title: "发送图片到 Localhost",
    contexts: ["image"] // 只在用户右键点击图片时显示
  });
});

// 监听右键菜单的点击事件
chrome.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "send-text") {
    // 处理发送文字
    handleSendText(tab.id);
  } else if (info.menuItemId === "send-image") {
    // 处理发送图片
    handleSendImage(info.srcUrl);
  }
});

// 处理发送文字的逻辑
async function handleSendText(tabId) {
  // 向当前标签页注入一个脚本来获取选中的文字
  const results = await chrome.scripting.executeScript({
    target: { tabId: tabId },
    function: () => {
      // 这个函数会在目标页面中执行
      return window.getSelection().toString().trim();
    }
  });

  // 检查是否获取到了文字
  if (results && results[0] && results[0].result) {
    const selectedText = results[0].result;
    sendDataToApi({ type: 'text', content: selectedText });
  } else {
    console.log("No text selected or could not retrieve text.");
    // 可以在这里添加一个通知提示用户
  }
}

// 处理发送图片的逻辑
function handleSendImage(imageUrl) {
  if (imageUrl) {
    sendDataToApi({ type: 'image', url: imageUrl });
  }
}

// 统一的发送数据到 API 的函数
async function sendDataToApi(data) {
  const apiUrl = 'http://localhost:3000/receiver'; // !! 修改为你的 API 地址 !!

  console.log('Sending data to API:', data);

  try {
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const result = await response.json();
    console.log('API Response:', result);
    // 可以在这里添加一个成功通知
    chrome.notifications.create({
      type: 'basic',
      iconUrl: 'icon.png',
      title: '发送成功',
      message: '数据已成功发送到本地 API。'
    });

  } catch (error) {
    console.error('Failed to send data to API:', error);
    // 可以在这里添加一个失败通知
    chrome.notifications.create({
      type: 'basic',
      iconUrl: 'icon.png',
      title: '发送失败',
      message: `无法连接到本地 API: ${error.message}`
    });
  }
}

代码解释

chrome.runtime.onInstalled: 在插件首次安装或更新时执行,我们用它来创建右键菜单。

contexts: ["selection"] 和 contexts: ["image"]: 这两个属性让菜单项只在特定上下文(选中文字或图片)时出现,非常智能。

chrome.scripting.executeScript: 这是 Manifest V3 的标准做法。我们向当前页面注入一个匿名函数 () => window.getSelection().toString().trim(),它的返回值就是用户选中的文字。

sendDataToApi: 这个函数封装了 fetch 请求,将数据以 POST 方式发送到指定的 API。它还包含了基本的错误处理和成功/失败通知。

注意:为了使用 chrome.notifications,你需要在 manifest.json 的 permissions 数组中添加 "notifications"。

第3步:创建一个简单的弹出窗口 popup.html (可选)

虽然核心功能通过右键菜单实现,但一个弹出窗口可以提供说明或状态信息。

popup.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        body { width: 300px; font-family: sans-serif; padding: 10px; }
        h3 { margin-top: 0; }
    </style>
</head>
<body>
    <h3>Send to Localhost</h3>
    <p>右键点击选中的文字或图片,然后选择 "发送到 Localhost"。</p>
    <p>确保你的本地 API 服务正在运行。</p>
</body>
</html>

第4步:创建一个本地测试服务器

为了测试插件,你需要一个在 localhost 运行的 HTTP 服务器。下面是一个使用 Node.js 和 Express 框架的简单示例。

安装 Node.js (如果尚未安装)。

创建一个新文件夹(例如 local-api),进入该文件夹。

在终端中运行 npm init -y。

运行 npm install express 安装 Express。

创建一个名为 server.js 的文件,内容如下:

server.js

const express = require('express');
const app = express();
const port = 3000; // 端口号,需要和 background.js 中的 apiUrl 匹配

// 这个中间件用于解析 JSON 格式的请求体
app.use(express.json());

// 定义接收数据的 POST 路由
app.post('/receiver', (req, res) => {
  console.log('--- Received Data ---');
  console.log(req.body);
  console.log('---------------------');

  // 根据数据类型做不同处理
  if (req.body.type === 'text') {
    console.log(`Received text: "${req.body.content}"`);
  } else if (req.body.type === 'image') {
    console.log(`Received image URL: ${req.body.url}`);
  }

  // 向插件发送一个成功响应
  res.status(200).json({ status: 'success', message: 'Data received successfully!' });
});

app.listen(port, () => {
  console.log(`Local API server listening at http://localhost:${port}`);
});

如何加载和测试

启动本地服务器:在 local-api 文件夹下,打开终端并运行 node server.js。你应该会看到 "Local API server listening at http://localhost:3000"。

准备插件文件:创建一个文件夹(例如 send-to-localhost),将 manifest.json, background.js, popup.html 和一个 icon.png (48x48) 放入其中。

加载插件

打开 Chrome,访问 chrome://extensions/。

打开右上角的 开发者模式

点击 加载已解压的扩展程序,选择你创建的 send-to-localhost 文件夹。

测试

测试文字:在任意网页上选中一段文字,右键点击,选择 "发送选中的文字到 Localhost"。

测试图片:在任意网页上右键点击一张图片,选择 "发送图片到 Localhost"。

查看结果:观察运行 node server.js 的终端窗口,你应该能看到打印出的 JSON 数据。同时,浏览器会弹出一个通知,告诉你发送成功或失败。

这样,你就拥有了一个功能完整、可以向本地 API 发送图片和文字的 Chrome 插件了!

网友回复

我知道答案,我要回答