Looker 的 Embed SDK 是一个函数库,您可以将其添加到基于浏览器的 Web 应用的代码中,以管理 Web 应用中的嵌入式信息中心、Look、报告和探索。
Embed SDK 通过以下方式简化了嵌入操作:
- 提供嵌入式内容的封装,无需手动创建 HTML 元素。
- 提供点对点通信,因此不存在跨框架通信。嵌入 SDK 会利用专用消息渠道处理宿主网页与嵌入式 Looker 内容之间的跨网域消息传递。
如果不使用 Embed SDK,您可以使用 JavaScript 事件(例如 嵌入式 JavaScript 事件文档页面中所述的 dashboard:run:start
或 page:changed
)来调用或响应嵌入式 Looker 内容中的事件。如果开发者使用 JavaScript 事件嵌入 Looker 内容,则必须创建 HTML 元素来存放嵌入的内容,并依靠窗口广播事件在 Web 应用和嵌入的内容之间进行通信。
请注意,Looker Embed SDK 与 Looker API 和 Looker API SDK 不同:
- Looker Embed SDK 位于 Web 应用的客户端代码中,用于管理 Looker 嵌入上下文和内容。(嵌入式 SDK 不提供对 Looker API 的访问权限。)
- Looker API 位于 Looker 实例所在的服务器上,并在 Looker 服务器上执行命令。
- Looker API 客户端 SDK 位于非浏览器应用的代码中,用于提供对 Looker API 函数的访问权限。
请注意,Looker 不控制浏览器向 Web 应用调度事件的顺序。这意味着,无法保证事件在不同浏览器或平台上的顺序。请务必妥善编写 JavaScript,以考虑不同浏览器的事件处理。
快速示例
在此示例中,系统会在 ID 为 embed_container
的 DOM 元素内创建一个 ID 为 11
的信息中心。dashboard:run:start
和 dashboard:run:complete
事件用于更新嵌入窗口的界面状态,而 ID 为 run
的按钮则通过脚本设置为向信息中心发送 dashboard:run
消息。
getEmbedSDK().init('looker.example.com', '/auth')
const setupConnection = (connection) => {
document.querySelector('#run').addEventListener('click', () => {
connection.asDashboardConnection().run()
})
}
try {
connection = await getEmbedSDK()
.createDashboardWithId('11')
.appendTo('#embed_container')
.on('dashboard:run:start', () => updateStatus('Running'))
.on('dashboard:run:complete', () => updateStatus('Done'))
.build()
.connect()
setupConnection(connection)
} catch (error) {
console.error('An unexpected error occurred', error)
}
如需查看更完整的示例,请参阅嵌入式 SDK 演示文档页面。
设置 Looker Embed SDK
Looker Embed SDK 使用的是流畅的接口模式。安装 Embed SDK 后,您就可以构建嵌入式内容并连接到嵌入式内容。建立连接后,宿主应用可能会与嵌入的内容互动。
安装 Embed SDK
您可以通过节点软件包管理器 (NPM) 从 https://www.npmjs.com/package/@looker/embed-sdk 获取 Looker 的嵌入 SDK 库。不过,如果您想查看示例代码或演示,则应改用 Looker Embed SDK 代码库。
如需使用 Looker 嵌入 SDK 代码库安装 Looker 嵌入 SDK,请按以下步骤操作:
- 安装 Node.js(如果尚未安装)。
- 下载或克隆
/looker-open-source/embed-sdk
代码库。 - 在终端窗口中,导航到
/embed-sdk
目录,然后运行以下命令:
npm install
npm start
构建嵌入内容
首先,使用 Looker 服务器的地址和嵌入应用服务器的端点初始化 SDK,该端点将创建已签名的 Looker 嵌入式登录网址。所有嵌入式内容都使用这些服务器。对于私密嵌入,请省略签名端点。
getEmbedSDK().init('looker.example.com', '/auth')
然后,系统会使用一系列步骤来定义嵌入式内容的参数,从而构建嵌入式内容。其中一些参数是可选的,另一些是必需的。
首先,您需要使用信息中心 id
或引用信息中心的 url
(通过已签名的嵌入文档页面上描述的流程创建)来创建构建器。
getEmbedSDK().createDashboardWithId('id')
或
getEmbedSDK().createDashboardWithUrl('url')
然后,您可以向构建器添加其他属性,以完成设置。
例如,您可以指定在网页中的哪个位置插入 Looker 嵌入式界面。以下调用会将 Looker 嵌入式界面放置在 ID 值为 dashboard
的 HTML 元素内:
.appendTo('#dashboard')
添加事件处理脚本:
.on('dashboard:run:start',
() => updateStatus('Running')
)
.on('dashboard:run:complete',
() => updateStatus('Done')
)
通过调用 build 方法创建嵌入式客户端:
.build()
连接到嵌入式内容
构建客户端后,调用 connect
以创建 iframe。连接过程会创建用于实际 iframe 的 src
属性。src
值的生成方式取决于嵌入式 SDK 的初始化方式:
- 已签名:调用
init
调用的第二个实参指定的端点。该端点应返回已签名的嵌入登录网址。 - 无 Cookie:系统会调用
initCookieless
调用的第二个实参指定的端点或函数。端点或函数应返回无 Cookie 令牌,特别是身份验证令牌和导航令牌。令牌会附加到嵌入式登录网址。 - 私密:如果未提供
init
调用的第二个实参,则嵌入连接是私密的。在这种情况下,网址是从构建器派生的,并使用 Looker 嵌入所需的参数进行修饰。对于私密嵌入,用户应已登录 Looker,或嵌入网址应包含allow_login_screen=true
参数。
connect
会返回一个 Promise
,该 Promise
会解析为嵌入式 iframe 的连接接口。
.connect()
.then((connection) => {
// Save the connection
})
.catch(console.error)
互动
嵌入式 SDK 2.0.0 会返回一个统一的连接,支持与所有 Looker 内容类型进行互动。嵌入式应用可以确定正在显示的内容类型,并相应地进行互动。
if (connection.getPageType() === 'dashboards') {
connection.asDashboardConnection().run()
} else (connection.getPageType() === 'looks') {
connection.asLookConnection().run()
} else (connection.getPageType() === 'explore') {
connection.asExploreConnection().run()
}
当需要加载不同的内容时,无需重新创建 iframe。不过,您可以使用连接方法 loadDashboard
、loadLook
、loadExplore
或 loadUrl
。loadDashboard
、loadLook
和 loadExplore
方法接受 id
。loadUrl
方法接受嵌入 URL
,此方法可用于指定其他参数(例如过滤条件)。
connection.loadDashboard('42')
// OR
connection.loadUrl('/embed/dashboards/42?state=california')
如果需要创建新的 iframe,Embed SDK 将不会再次调用签名或获取会话端点。而是直接从构建器构建 iframe src
。如果需要创建新的嵌入会话,则需要按以下方式重新初始化 Embed SDK:
getEmbedSDK(new LookerEmbedExSDK()).init('looker.example.com', '/auth')
签名网址身份验证端点
本部分不适用于无 Cookie 嵌入。如需了解详情,请参阅无 Cookie 嵌入。
如需使用嵌入 SDK,您必须提供一个用于处理嵌入网址签名的后端服务。嵌入 SDK 会调用此服务来生成请求用户的唯一签名网址。后端进程可以使用嵌入 Secret 本身生成已签名的嵌入网址,也可以通过调用 Looker Create Signed Embed 网址 API 来生成网址。手动生成和签名网址可避免调用 Looker API,从而缩短延迟时间。调用 Looker API 所需的代码更少,也更易于维护。
您可以在 server/utils/auth_utils.ts 中找到生成签名网址 createSignedUrl()
的辅助方法的 JavaScript 示例。它用于以下方面:
import { createSignedUrl } from './utils/auth_utils'
app.get('/looker_auth', function (req, res) {
// It is assumed that the request is authorized
const src = req.query.src
const host = 'looker.example.com'
const secret = ... // Embed secret from Looker Server Embed Admin page
const user = ... // Embedded user definition
const url = createSignedUrl(src, user, host, secret)
res.json({ url })
})
请参阅代码库中的 Python 示例。
签名网址高级身份验证配置
本部分不适用于无 Cookie 嵌入。如需了解详情,请参阅无 Cookie 嵌入。
您可以通过向 init
方法传递一个 options 对象来配置身份验证端点,以允许自定义请求标头和 CORS 支持。
getEmbedSDK().init('looker.example.com', {
url: 'https://api.acme.com/looker/auth',
headers: [{ name: 'Foo Header', value: 'Foo' }],
params: [{ name: 'foo', value: 'bar' }],
withCredentials: true, // Needed for CORS requests to Auth endpoint include Http Only cookie headers
})
问题排查
嵌入 SDK 基于 chatty 构建而成。Chatty 使用 debug 进行日志记录。您可以在浏览器控制台中使用以下命令启用日志记录:
localStorage.debug = 'looker:chatty:*'
```none
Note that both the parent window and the embedded content have separate local storage, so you can enable logging on one, the other, or both. You can disable logging with this command:
```javascript
localStorage.debug = ''