我正在遵循本教程https://www.tetranyde.com/blog/embedding-superset尝试在React Js应用程序中嵌入superset仪表板。
我也加入了我的服务器代码:server.js
import express from "express"
import fetch from "node-fetch"
import cors from "cors"
const PORT = 3001
const app = express()
// Enable CORS
app.use(cors())
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`)
})
async function fetchAccessToken() {
try {
const body = {
username: "admin",
password: "admin",
provider: "db",
refresh: true,
}
const response = await fetch(
"http://localhost:8088/api/v1/security/login",
{
method: "POST",
body: JSON.stringify(body),
headers: {
"Content-Type": "application/json",
},
}
)
const jsonResponse = await response.json()
return jsonResponse?.access_token
} catch (e) {
console.error(error)
}
}
async function fetchGuestToken() {
const accessToken = await fetchAccessToken()
try {
const body = {
resources: [
{
type: "dashboard",
id: "2962c53b-3364-4ad9-b4bd-35f0ff69e909",
},
],
rls: [],
user: {
username: "guest",
first_name: "Guest",
last_name: "User",
},
}
const response = await fetch(
"http://localhost:8088/api/v1/security/guest_token",
{
method: "POST",
body: JSON.stringify(body),
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
}
)
const jsonResponse = await response.json()
return jsonResponse?.token
} catch (error) {
console.error(error)
}
}
app.get("/guest-token", async (req, res) => {
const token = await fetchGuestToken()
res.json(token)
})
和我的 React Home 组件代码:
import React from 'react'
import { useEffect } from "react"
import { embedDashboard } from "@superset-ui/embedded-sdk"
function Home() {
const getToken = async () => {
const response = await fetch("/guest-token")
const token = await response.json()
return token
}
useEffect(() => {
const embed = async () => {
await embedDashboard({
id: "2962c53b-3364-4ad9-b4bd-35f0ff69e909", // given by the Superset embedding UI
supersetDomain: "http://localhost:8088",
mountPoint: document.getElementById("dashboard"), // html element in which iframe render
fetchGuestToken: () => getToken(),
dashboardUiConfig: {
hideTitle: true,
hideChartControls: true,
hideTab: true,
},
})
}
if (document.getElementById("dashboard")) {
embed()
}
}, [])
return (
<div className="App">
<h1>How to Embed Superset Dashboard </h1>
<div id="dashboard" style={{width:'100%',height:'800px'}}/>
</div>
)
}
export default Home
我认为服务器有问题,但我无法弄清楚
将错误文本粘贴到此处以方便阅读:
拒绝显示'http://localhost/8088' 在框架中,因为它将“X-Frame-Options”设置为“SAMEORIGIN”
发生这种情况是因为服务器的响应正在设置 iframe 安全性以强制同源。理论上您应该能够使用
编辑
superset_config.py
文件
OVERRIDE_HTTP_HEADERS = {'X-Frame-Options': 'ALLOWALL'}
但这对我不起作用。相反,罪魁祸首是 Superset 服务器使用的 Talisman 库,它为 iframe 默认设置相同的源设置。
要解决这个问题,您必须修改默认的 Talisman 设置或通过配置关闭 Talisman
TALISMAN_ENABLED = False
无法在“DOMWindow”上执行“postMessage”:提供的目标源 ('http://localhost:8088') 与收件人窗口的来源不匹配 (空)。
发生这种情况是因为之前的错误,因为 iframe 未加载 iframe 原点是
null
,因此出现异常。