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 发送请求,头部带的 CORS 为 http://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 访问我。”
此时:
- n8n 收到 Wails 的请求 (
Origin: http://wails.localhost:34115)。 - n8n 检查配置,发现这个 Origin 精确匹配。
- n8n 在响应头部中设置
Access-Control-Allow-Origin: http://wails.localhost:34115。 - Wails 环境的浏览器接收到响应,发现 Origin 匹配,CORS 通过,请求成功。
结论: 在开发环境中,尤其是 Origin 是非标准域(如 localhost 或 wails.localhost)时,明确列出 Origin 比使用 * 更健壮,可以避免许多潜在的服务器端 CORS 逻辑问题。
结语
上面跨域的问题,应该是非简单请求导致跨域失败,最终转向我 n8n 服务域名导致的问题。
非简单请求(如带有自定义头部或特定 MIME 类型的 POST 请求,n8n Chat 的复杂请求可能属于此类)不允许使用Access-Control-Allow-Origin: *。在这种情况下,服务器必须明确回传请求中的Origin头部,即:Access-Control-Allow-Origin: http://wails.localhost:34115。
大概就是这样子,没了。
RoLingG | 博客
评论(0)