N

[n8n] Chat+Agent公开化嵌入前端及相关跨域问题

RoLingG 其他 2025-11-08

n8n chat+agent公开化嵌入前端及相关跨域问题

官方文档:https://www.npmjs.com/package/@n8n/chat

完整嵌入前端代码:

<div id="n8n-chat"></div>
<link href="https://cdn.jsdelivr.net/npm/@n8n/chat/dist/style.css" rel="stylesheet" />
<script type="module">
    import '@n8n/chat/style.css';
    import { createChat } from '@n8n/chat';

    createChat({
        webhookUrl: 'https://***.***.***/webhook/a****e-2***9-***f-***6-5*******e/chat',
        target: '#n8n-chat',
        showWelcomeScreen: true,
        initialMessages: [
            '喵啦喵喵 👋',
            '我是米雪儿喵,我能帮到你什么喵?'
        ],
        loadPreviousSession: true,
        metadata: {},
        defaultLanguage: 'en',
        i18n: {
            en: {
                title: '喵啦喵喵 👋',
                subtitle: "24/7 全天候帮助你喵",
                footer: '',
                getStarted: 'New Conversation',
                inputPlaceholder: 'Type your question..',
            },
        },
        enableStreaming: false,
    });
</script>

<style>
    #n8n-chat .chat-window {
        width: 400px;
        height: 800px;
    }

    #n8n-chat .chat-header {
        background-color: #a4e1a4;
        color: #000000;
        padding: 0px 40px 0px 40px;
        min-height: auto;
    }

    #n8n-chat .chat-heading h1 {
        color: #000000;
        font-size: 1.5em;
        margin: 0 0 5px 0;
        opacity: 1;
    }

    #n8n-chat .chat-footer button {
        background-color: #00796b;
        color: #ffffff;
    }
    #n8n-chat .chat-footer textarea {
        color: #101330;
    }

    #n8n-chat .chat-window-toggle {
        background-color: #00796b;
    }

    #n8n-chat .chat-window button {
        background-color: #00796b;
        color: #ffffff;
        border: none;
        border-radius: 8px;
    }

    #n8n-chat .chat-window button:hover {
        background-color: #006056;
    }
</style>

不知道为什么官方文档的 :root ,直接适配进 style 里生效不了,所以就直接对着 :root 的指定元素用了 css 覆盖实现自定义样式。

另外

不知道为什么我在 wails dev 里面对 n8n chat 给的 webhook 发送请求,头部带的 CORShttp://wails.localhost:34115,然后 chat 里面的 CORS 设定的范围是 *,但是请求就是发不过来,会转向我云服务器部署 n8n 服务对应的域名,一定要明确指向 http://wails.localhost:34115 才可以。

GPT的回答是:

1. Wails Dev 环境的 CORS 头部

在 Wails 开发模式下,你的前端代码运行在一个基于 Webview 的浏览器环境中,其源(Origin)是 http://wails.localhost:34115

2. n8n 的 CORS 设置 (*) 的限制

当你将 n8n 的 Allowed Origins (CORS) 设置为 * (允许所有来源) 时,你期望它能接受任何域名的请求。

然而,在许多服务器和框架(包括 n8n 的底层 Node.js/Express 框架)中,当 Access-Control-Allow-Origin 响应头被设为 * 时,它通常意味着:

  • 简单请求(GET, POST, HEAD,且不包含特殊头部)可以被接受。
  • 非简单请求(如带有自定义头部或特定 MIME 类型的 POST 请求,n8n Chat 的复杂请求可能属于此类)不允许使用 Access-Control-Allow-Origin: *。在这种情况下,服务器必须明确回传请求中的 Origin 头部,即:Access-Control-Allow-Origin: http://wails.localhost:34115

3. 为什么会“转向”你的云服务器域名?

你提到“会转向我云服务器部署 n8n 服务对应的域名”。这强烈表明你的 n8n 服务 URL 实际上是经过了反向代理(例如 Nginx 或宝塔面板,如你的截图所示)部署的。

当发生请求失败或重定向时,浏览器/Wails 可能尝试从最终的、暴露在公网上的域名发送 CORS 请求,或者在日志中显示这个域名,但实际的 CORS 头部仍然是 Wails 的本地地址。

核心原因: 当 n8n 接收到带有 Origin: http://wails.localhost:34115 的请求时,如果它的 CORS 列表是 *,它可能无法正确处理这个非公网的、本地的 Origin,导致预检请求(Preflight Request,一个 OPTIONS 请求)失败。

4. 明确指向的必要性

当你将 n8n 的 CORS 设置从 * 改为 明确的 http://wails.localhost:34115 时,你告诉了 n8n 服务器:“我只允许这个特定的 Origin 访问我。”

此时:

  1. n8n 收到 Wails 的请求 (Origin: http://wails.localhost:34115)。
  2. n8n 检查配置,发现这个 Origin 精确匹配
  3. n8n 在响应头部中设置 Access-Control-Allow-Origin: http://wails.localhost:34115
  4. Wails 环境的浏览器接收到响应,发现 Origin 匹配,CORS 通过,请求成功。

结论: 在开发环境中,尤其是 Origin 是非标准域(如 localhostwails.localhost)时,明确列出 Origin 比使用 * 更健壮,可以避免许多潜在的服务器端 CORS 逻辑问题。

结语

上面跨域的问题,应该是非简单请求导致跨域失败,最终转向我 n8n 服务域名导致的问题。

非简单请求(如带有自定义头部或特定 MIME 类型的 POST 请求,n8n Chat 的复杂请求可能属于此类)不允许使用 Access-Control-Allow-Origin: *。在这种情况下,服务器必须明确回传请求中的 Origin 头部,即:Access-Control-Allow-Origin: http://wails.localhost:34115

大概就是这样子,没了。

PREV
[MySQL] MySQL遇到内存都装不下的数据表,如果要进行去重,该如何操作?
NEXT
[Raft] 关于Raft的一些学习

评论(0)

发布评论