Skip to content

Coco-AI 支持嵌入,让你的网站拥有 AI 搜索力

Coco-AI 支持嵌入,让你的网站支持 AI 搜索

在之前的文章中,我们让 Hexo,hugo 博客 支持了 coco AI 检索,也就是说我们还得使用客户端来检索,那是不是把搜索放在博客上呢?

Coco-AI 在 0.3 的版本中

image-20250402213914361


先找一个 html 来看个效果。

html
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>搜索组件嵌入示例</title>
    <style>
      body {
        font-family: sans-serif;
        padding: 2rem;
      }
      #searchbox {
        margin-top: 20px;
        border: 1px solid #ccc;
        padding: 16px;
        border-radius: 8px;
      }
    </style>
  </head>
  <body>
    <h1>欢迎使用 Cloudsmithy 搜索组件</h1>
    <p>下面是通过 ES Module 引入的搜索框:</p>

    <div id="searchbox"></div>

    <script type="module">
      import { searchbox } from "http://localhost:9000/integration/cvmhvjl92jog2dokvsd0/widget";

      searchbox({
        container: "#searchbox",
      });
    </script>
  </body>
</html>

💡 原始代码:

html
<div id="searchbox"></div>
<script type="module">
  import { searchbox } from "http://localhost:9000/integration/cvmhvjl92jog2dokvsd0/widget";
  searchbox({ container: "#searchbox" });
</script>

🧩 每部分解析

1. <div id="searchbox"></div>

这是一个空的 div 元素,作为挂载容器。你的 searchbox 组件会被渲染进这个 div

  • 就像 React 或 Vue 应用会挂载到 <div id="app"> 一样
  • 你在这里指定了 id 为 searchbox,用于后面初始化组件时绑定

2. <script type="module">

这表示:这是一个 ES Module 格式的 JavaScript 脚本

  • 现代浏览器支持原生的模块化加载(无需打包器)
  • 可以使用 import 加载其他模块、组件

3. import { searchbox } from "http://localhost:9000/integration/cvmhvjl92jog2dokvsd0/widget";

从远程地址(本地服务器)中导入 searchbox 函数:

  • 说明这个 URL 返回的是一个 JavaScript 模块,里面导出了 searchbox

  • 类似 Vue、React 中的组件库导入:

    js
    import { Button } from "element-plus";

调用 searchbox 函数,初始化组件,并挂载到页面中:

  • 参数是一个对象,指明组件要渲染在哪个 DOM 元素里
  • container: "#searchbox" 通过 CSS 选择器指定了上面那个 div

🧠 通俗类比

就像你在网页上写:

html
<div id="chat"></div>
<script type="module">
  import { chatWidget } from "./chat.js";
  chatWidget({ container: "#chat" });
</script>

它就是在某个 div 中挂载一个聊天插件一样。你这段代码的本质就是嵌入并运行一个远程提供的 JS 组件。


✅ 总结一句话:

这段代码的作用是:

把远程加载的 searchbox 组件挂载到网页上的 <div id="searchbox"> 中,完成动态插入功能。


如果你希望我反向帮你写出那个 searchbox 模块怎么写,或者做成本地文件测试,也可以告诉我~

下面是一个可以在任意网站自动嵌入你给出的 <div><script> 的油猴(Tampermonkey)脚本示例:


✅ 功能说明

  • 在页面加载完成后,向 <body> 插入一个 #searchboxdiv
  • 加载你的远程模块并初始化 searchbox 组件

一开始打算在 hexo 的组件上改,但是在编译阶段有问题,索性使用油猴脚本来实现

🐵 Tampermonkey 脚本示例

javascript
// ==UserScript==
// @name         Searchbox Embedder
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  在任意网页中注入 searchbox 小部件
// @author       You
// @match        *://*/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
  "use strict";

  // 创建 searchbox 容器
  const searchboxDiv = document.createElement("div");
  searchboxDiv.id = "searchbox";
  document.body.appendChild(searchboxDiv);

  // 动态加载模块脚本(ESM)
  const script = document.createElement("script");
  script.type = "module";
  script.textContent = `
        import { searchbox } from "http://localhost:9000/integration/cvmhvjl92jog2dokvsd0/widget";
        searchbox({ container: "#searchbox" });
    `;
  document.body.appendChild(script);
})();

⚠️ 注意事项

  1. 浏览器必须支持 ES Module。
  2. 若该域名不是 HTTPS,确保目标网页也是 HTTP,否则会被浏览器拦截跨协议内容。
  3. 若需局部生效,请将 @match 改为具体的页面,例如:https://example.com/*


🌟 脚本整体作用

这个油猴脚本的作用是:在任何网页上自动插入一个 div#searchbox 容器,并加载你提供的远程模块脚本,渲染搜索框组件


📜 脚本逐行解析

javascript
// ==UserScript==
// @name         Searchbox Embedder
  • @name 是脚本的名字,显示在 Tampermonkey 的控制面板中。
javascript
// @namespace    http://tampermonkey.net/
  • 命名空间,可以用来区分多个脚本的作者或用途(不重要)。
javascript
// @version      0.1
  • 脚本版本号。
javascript
// @description  在任意网页中注入 searchbox 小部件
  • 简要说明这个脚本做什么。
javascript
// @author       You
  • 作者名,可以改成你自己的。
javascript
// @match        *://*/*
  • 匹配所有网站页面。如果你只想对某个特定网站注入,可将它改为: // @match https://example.com/*
javascript
// @grant        none
  • 没有使用 Tampermonkey 的特殊权限(如 GM_* 方法),所以可以写 none
javascript
// @run-at       document-end
  • 脚本在 DOM 加载完成后执行(类似 DOMContentLoaded)。

💻 主体逻辑解析

javascript
(function () {
    'use strict';
  • 启用严格模式,避免某些低级错误。
javascript
// 创建 searchbox 容器
const searchboxDiv = document.createElement("div");
searchboxDiv.id = "searchbox";
document.body.appendChild(searchboxDiv);
  • 创建一个 <div id="searchbox"> 并插入到 <body> 中,作为挂载点。
javascript
// 动态加载模块脚本(ESM)
const script = document.createElement("script");
script.type = "module";
  • 创建一个新的 <script type="module">,用来加载 ES 模块。
javascript
script.textContent = `
        import { searchbox } from "http://localhost:9000/integration/cvmhvjl92jog2dokvsd0/widget";
        searchbox({ container: "#searchbox" });
    `;
  • 直接把模块内容写入 script 标签中:
    • 从你本地地址加载 searchbox 组件
    • 调用 searchbox({ container: "#searchbox" }) 初始化它
javascript
    document.body.appendChild(script);
})();
  • 把这个 <script type="module"> 插入到 <body> 中,触发模块加载和执行。

✅ 总结

这个脚本做了三件事:

  1. 在网页中插入一个 div#searchbox
  2. 动态加载你本地的模块组件
  3. 初始化这个组件并挂载到 #searchbox
❤️喜欢