[帮助] 需要帮助将网站参数解析并嵌入到 Dify Chatflow(通过 iFrame 嵌入)

大家好,

我需要一些帮助,将我网站上的参数解析到 Dify Chatflow 中。

我目前的设置如下:

  • 我正在使用 Dify Cloud
  • Chatflow 已发布并嵌入在我的网站中,通过 发布的 URL 嵌入在 iframe 中。

我的目标是将网站上的参数(例如用户信息或会话数据)传递到 Dify Chatflow,以便聊天机器人可以处理或显示这些参数。

我已经尝试过使用脚本并参考了有关参数传递的文档,但遗憾的是,似乎没有起作用。

请问有人能指导我如何在通过 iframe 嵌入时正确地向 Dify Chatflow 发送或解析参数吗?
任何示例或可行的实现都将非常感谢!

提前感谢大家的帮助!

你好 @cuifangxu

感谢你的帮助!我想确认一下与 Dify + Chatflow 相关的几个实现细节,特别是关于同源策略(Same-Origin Policy)和消息处理的部分:

1. 部署 — 同源策略

为解决同源策略限制,是否建议将 Dify 安装在与网站相同的服务器/环境中(例如,本地安装在同一主机上)?如果不是,推荐的方案是什么(CORS、反向代理,或将 Dify 与网站部署在同一源下)?

2. 在 Dify / Chatflow 中接收消息

对于从父窗口通过 postMessage 发送的数据,我是否需要在 Dify 内部添加 window.addEventListener('message', ...) 事件监听器?还是 Dify 会自动填充所需变量?如果必须手动添加监听器,能否提供一个与 Dify/Chatflow 集成的分步示例?我目前使用的是 Chatflow,希望了解接收并使用传入参数(如 user_id、user_name、session_id)的最佳方式。

附注 — 我通常在应用中获取 postMessage 值的示例:

window.addEventListener('message', function(event) {
    // 仅接受来自预期源的消息
    if (event.origin !== 'https://my-parent-domain.com') {
        return;
    }

    if (event.data && event.data.type === 'DIFY_PARAMS') {
        const receivedData = event.data.data;

        console.log('从父窗口接收到的用户数据:');
        console.log('用户 ID:', receivedData.user_id);
        console.log('用户名:', receivedData.user_name);
        console.log('会话 ID:', receivedData.session_id);
    } else {
        console.log('收到一条消息,但类型不是 DIFY_PARAMS:', event.data);
    }
}, false);

console.log('Iframe 正在监听 postMessages...');

请求: 请告知此方法是否适用于 Dify Chatflow,如需调整,请提供简明的分步指南,说明如何:

  • 在 Dify/Chatflow 内部添加 message 事件监听器;
  • 验证并映射传入字段至 Dify 变量或 Chatflow 上下文;
  • 任何推荐的安全检查或最佳实践(如源验证、消息结构验证、拒绝意外消息、回复时使用 event.source 等)。

提前感谢你的帮助!

image

image

iframe

<!DOCTYPE html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Iframe Chatbot</title>
</head>
<body>
    <h1>Iframe Chatbot</h1>
    
    <script>
        // 定义要编码的变量
        const inputs = {
            "user_name": "Tom"
        };

        // 编码函数
        async function compressAndEncode(input) {
            const uint8Array = new TextEncoder().encode(input);
            const compressedStream = new Response(
                new Blob([uint8Array])
                    .stream()
                    .pipeThrough(new CompressionStream("gzip"))
            ).arrayBuffer();
            const compressedUint8Array = new Uint8Array(await compressedStream);
            return btoa(String.fromCharCode(...compressedUint8Array));
        }

        // 生成编码后的 URL
        (async () => {
            const params = new URLSearchParams();
            for (const [key, value] of Object.entries(inputs)) {
                params.append(key, await compressAndEncode(value));
            }

            const baseUrl = "http://localhost/chatbot/nF6Zbpsxk2Hc5vxE";
            const iframeUrl = `${baseUrl}?${params.toString()}`;

            // 更新 iframe 的 src
            document.querySelector("iframe").src = iframeUrl;
        })();
    </script>
    
    <iframe
      src="about:blank"
      style="width: 100%; height: 100%; min-height: 700px"
      frameborder="0"
      allow="microphone">
    </iframe>
</body>
</html>

script

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Script Chatbot</title>
</head>
<body>
    <h1>Script Chatbot</h1>
    
    <script>
      window.difyChatbotConfig = {
        token: 'nF6Zbpsxk2Hc5vxE',
        baseUrl: 'http://localhost',
        inputs: {
        // 可在此处定义来自开始节点的输入
        // key 是变量名
          user_name: "Tom"
        }
      }
    </script>
    <script
      src="http://localhost/embed.min.js"
      id="nF6Zbpsxk2Hc5vxE"
      defer>
    </script>
</body>
</html>

非常感谢您的帮助。我已经测试了该解决方案,它在我的端上运行良好。但是,URL 需要设置为 http://localhost/chatbot/nF6Zbpsxk2Hc5vxE。当我使用 http://localhost/chat/nF6Zbpsxk2Hc5vxE 时,参数值无法正确解码。我使用 /chat 路径来显示聊天历史侧边栏,因为 /chatbot 路径不会显示侧边面板。

这种情况更简单——只需直接将参数附加到URL上,无需压缩和编码。

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Iframe Chatbot</title>
</head>
<body>
    <h1>Iframe Chatbot</h1>
    
    <script>
        const inputs = {
            "user_name": "Tom"
        };

        document.addEventListener('DOMContentLoaded', async () => {
            const params = new URLSearchParams();
            for (const [key, value] of Object.entries(inputs)) {
                params.append(key, value);
            }

            const baseUrl = "http://localhost/chat/WMnzIe1JaO25EwIq";
            const iframeUrl = `${baseUrl}?${params.toString()}`;

            const iframe = document.createElement('iframe');
            iframe.src = iframeUrl;
            iframe.style.width = '100%';
            iframe.style.height = '100%';
            iframe.style.minHeight = '700px';
            iframe.frameBorder = '0';
            iframe.allow = 'microphone';

            document.body.appendChild(iframe);
        });
    </script>
</body>
</html>