使用Looker EmbedSDK通过SSO URL时connect() Promise始终无法解析
问题描述
通过SSO URL嵌入Looker仪表盘时,connect()方法的Promise始终无法resolve。iframe能正常渲染仪表盘,但SDK无法建立连接。
调试细节
@looker/chatty的host.js中,evt.data.action始终为undefined,导致switch分支无法命中Syn消息,连接流程卡壳。- 日志输出:
looker:chatty:host window received +0ms undefined undefined - 捕获到的postMessage数据:
{"type":"page:changed","page":{"type":"dashboard","absoluteUrl":"https://company.looker.com:19999/embed/dashboards/104?embed_domain=http://localhost:3100","url":"/embed/dashboards/104?embed_domain=http://localhost:3100"}}
该数据没有action和data字段,不符合Chatty SDK的通信格式。
已验证配置
localhost:3100已加入Looker嵌入允许列表- SSO URL包含
embed_domain=http://localhost:3100&sdk=2参数
前端嵌入代码
const [embed, setEmbed] = useState<LookerEmbedDashboard>(); const embedUrl = useLookerSSOEmbed(dashboard); const embedCtrRef = useCallback( (el) => { if (el && embedUrl) { el.innerHTML = ''; LookerEmbedSDK.init('https://company.looker.com:19999'); LookerEmbedSDK.createDashboardWithUrl(embedUrl) .appendTo(el) .build() .connect() .then((dashboard) => { setEmbed(dashboard); console.log('dashboard', dashboard); }) .catch((error) => console.log('error', error)); } }, [embedUrl] ); return <EmbedContainer ref={embedCtrRef}></EmbedContainer>;
问题定位
@looker/chatty的windowListener函数依赖evt.data.action判断消息类型,但当前收到的是Looker页面跳转通知(page:changed),而非SDK连接所需的Syn消息,导致连接流程无法推进:
var windowListener = function (evt) { if (!_this.isValidMsg(evt)) { ChattyHost._debug('window received invalid', evt); return; } ChattyHost._debug('window received', evt.data.action, evt.data.data); switch (evt.data.action) { case client_messages_1.ChattyClientMessages.Syn: // 连接逻辑 break; } };
解决步骤
校验
embed_domain参数一致性
确保SSO URL中的embed_domain与前端应用的域名完全匹配,包括协议(http/https)和端口号,比如http://localhost:3100不能写成localhost:3100或http://localhost。调整SDK版本参数
如果Looker服务器版本较旧,可能不兼容SDK v2,尝试将SSO URL中的sdk=2改为sdk=1,再测试连接。避免重复初始化SDK
代码中每次embedUrl更新都会重新调用LookerEmbedSDK.init(),可能导致通信冲突。将初始化逻辑移到组件外部,全局仅执行一次:// 全局初始化,放在组件定义前 LookerEmbedSDK.init('https://company.looker.com:19999'); const DashboardEmbed = () => { const [embed, setEmbed] = useState<LookerEmbedDashboard>(); const embedUrl = useLookerSSOEmbed(dashboard); const embedCtrRef = useCallback( (el) => { if (el && embedUrl) { el.innerHTML = ''; LookerEmbedSDK.createDashboardWithUrl(embedUrl) .appendTo(el) .build() .connect() .then((dashboard) => { setEmbed(dashboard); console.log('dashboard', dashboard); }) .catch((error) => console.log('error', error)); } }, [embedUrl] ); return <EmbedContainer ref={embedCtrRef}></EmbedContainer>; };检查嵌入权限与CSP设置
确认Looker实例的嵌入允许列表中已正确添加前端域名,且服务器端没有配置限制postMessage的CSP规则。升级依赖包
旧版本的@looker/chatty或@looker/embed-sdk可能存在消息解析bug,执行以下命令升级到最新兼容版本:npm update @looker/chatty @looker/embed-sdk
内容的提问来源于stack exchange,提问作者Trevor Hewitt

