diff --git a/dify_1.4.0/web/app/components/base/iframe-postmessage.tsx b/dify_1.4.0/web/app/components/base/iframe-postmessage.tsx new file mode 100644 index 00000000..4a2f3b88 --- /dev/null +++ b/dify_1.4.0/web/app/components/base/iframe-postmessage.tsx @@ -0,0 +1,80 @@ +'use client' +import { useEffect, useRef } from 'react' + +/** + * IframePostMessage + * 页面加载完成后向父页面发送一次消息,并每 5 秒发送一次。 + * 仅当当前窗口运行在 iframe 中时才发送。 + */ +const IframePostMessage = () => { + const initializedRef = useRef(false) + + /** + * sendMessage + * 向父页面发送消息的函数:收集当前页面的 localStorage 全量键值并发送。 + * 如果不在 iframe 环境中则不发送。 + */ + const sendMessage = () => { + try { + if (typeof window === 'undefined') return + // 只在 iframe 环境下发送 + if (window.parent === window) return + // 收集 localStorage 全量数据 + const localStorageData: Record = {} + try { + const { localStorage } = window + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i) + if (!key) continue + localStorageData[key] = localStorage.getItem(key) + } + } + catch { + // 可能因浏览器隐私设置导致不可访问 localStorage + } + window.parent.postMessage( + { + type: 'dify-localstorage', + status: 1, + message: '将智能体本地缓存发送给父页面!', + data: localStorageData, + }, + '*', + ) + } + catch { + // 忽略跨域或其他运行时错误 + } + } + + useEffect(() => { + if (initializedRef.current) return + initializedRef.current = true + + let timer: number | undefined + + const init = () => { + sendMessage() + timer = window.setInterval(sendMessage, 5000) + } + + if (document.readyState === 'loading') { + const onReady = () => { + init() + document.removeEventListener('DOMContentLoaded', onReady) + } + document.addEventListener('DOMContentLoaded', onReady) + } + else { + init() + } + + return () => { + if (timer) window.clearInterval(timer) + } + }, []) + + return null +} + +export default IframePostMessage \ No newline at end of file diff --git a/dify_1.4.0/web/app/layout.tsx b/dify_1.4.0/web/app/layout.tsx index ba2be054..35b0485e 100644 --- a/dify_1.4.0/web/app/layout.tsx +++ b/dify_1.4.0/web/app/layout.tsx @@ -8,6 +8,7 @@ import { TanstackQueryIniter } from '@/context/query-client' import { ThemeProvider } from 'next-themes' import './styles/globals.css' import './styles/markdown.scss' +import IframePostMessage from './components/base/iframe-postmessage' export const metadata = { title: '深圳燃气智能体共创平台', @@ -77,6 +78,7 @@ const LocaleLayout = async ({ + )