在Django应用中嵌入Apache Superset仪表盘遇阻求助
Django嵌入Apache Superset仪表盘失败排查与解决
背景信息
- Django应用运行在
localhost:8000,Apache Superset运行在localhost:8088(已启用嵌入功能),二者无法协同工作 - Django已登录用户需查看Superset中创建的仪表盘
- 已在Django中实现工具函数获取Superset guest token(对应拥有Public和Gamma权限的用户)
- 已将
guest_token和仪表盘embed ID传递至模板 - 用户访问页面时仅显示灰色小区域,提示“127.0.0.1拒绝连接”
当前模板代码
{% extends 'base_logged_in.html' %} {% block extra_head %} <script src="https://unpkg.com/@superset-ui/embedded-sdk"></script> {% endblock extra_head %} {% block content %} <h1>{{ page.name }}</h1> <div class="container"> <!-- 嵌入仪表盘的挂载容器 --> <div id="my-superset-container" style="height: 1920px; width: 100%;"></div> <script> document.addEventListener('DOMContentLoaded', function () { if ("{{ guest_token }}" && "{{ superset_embed_id }}") { supersetEmbeddedSdk.embedDashboard({ id: "{{ superset_embed_id }}", supersetDomain: "{{ settings.SUPERSET_SITE_URL }}", mountPoint: document.getElementById("my-superset-container"), fetchGuestToken: () => Promise.resolve("{{ guest_token }}"), dashboardUiConfig: { hideTitle: true, filters: { expanded: true, } }, }).catch(error => { console.error('Error embedding Superset dashboard:', error); }); } else { console.error('Missing Superset embed ID or guest token.'); } }); </script> </div> {% endblock %}
错误信息
控制台错误
Refused to display 'http://127.0.0.1:8000/' in a frame because it set 'X-Frame-Options' to 'deny'. Failed to load resource: the server responded with a status of 404 () Uncaught DOMException: Failed to execute 'postMessage' on 'Window': Invalid target origin '' in a call to 'postMessage'. at HTMLIFrameElement.<anonymous> (https://unpkg.com/@superset-ui/embedded-sdk:1:7125)
网络请求错误
Page not found (404) Request Method: GET Request URL: http://127.0.0.1:8000/embedded/<embed-code-from-superset>?uiConfig=1&expand_filters=true
问题排查与修复方案
1. 404错误核心原因:请求目标地址错误
网络请求显示请求发往了Django的/embedded/路径,但该端点属于Superset,说明supersetDomain配置错误:
- 检查Django的
settings.SUPERSET_SITE_URL是否正确设置为http://localhost:8088,确认没有遗漏端口或写错域名 - 可先在模板中直接写死
supersetDomain: "http://localhost:8088"测试,排除配置变量的问题
2. X-Frame-Options限制问题
错误提示Django设置了X-Frame-Options: deny,同时Superset端也需要允许跨域嵌入:
- Django端:若需在页面中嵌入iframe,可通过中间件修改
X-Frame-Options为SAMEORIGIN,或直接移除该响应头(仅限信任场景) - Superset端:确保配置文件中
SUPERSET_WEBSERVER_ENABLE_CORS = True、SUPERSET_EMBEDDED_SDK_ENABLED = True,并在SUPERSET_CORS_OPTIONS中添加Django域名http://localhost:8000
3. postMessage目标源错误
当supersetDomain为空或错误时,SDK会使用空目标源调用postMessage,修正supersetDomain后该问题会自动解决
4. 额外验证步骤
- 直接访问Superset的嵌入地址
http://localhost:8088/embedded/<你的embed-id>,确认仪表盘能正常加载 - 检查guest token权限:确保该token对应的用户有权限访问目标仪表盘
- 清除浏览器缓存,避免旧配置残留
修正后的模板代码示例
{% extends 'base_logged_in.html' %} {% block extra_head %} <script src="https://unpkg.com/@superset-ui/embedded-sdk"></script> {% endblock extra_head %} {% block content %} <h1>{{ page.name }}</h1> <div class="container"> <div id="my-superset-container" style="height: 1920px; width: 100%;"></div> <script> document.addEventListener('DOMContentLoaded', function () { if ("{{ guest_token }}" && "{{ superset_embed_id }}") { supersetEmbeddedSdk.embedDashboard({ id: "{{ superset_embed_id }}", supersetDomain: "http://localhost:8088", mountPoint: document.getElementById("my-superset-container"), fetchGuestToken: () => Promise.resolve("{{ guest_token }}"), dashboardUiConfig: { hideTitle: true, filters: { expanded: true, } }, }).catch(error => { console.error('嵌入Superset仪表盘失败:', error); }); } else { console.error('缺少Superset嵌入ID或guest token'); } }); </script> </div> {% endblock %}
内容的提问来源于stack exchange,提问作者nik
相关产品推荐
相关产品推荐

