Looker 的嵌入 SDK 是一个函数库,您可以将其添加到基于浏览器的 Web 应用的代码中,以便在 Web 应用中管理嵌入的 Dashboard、Look、报告和探索。
Embed SDK 通过以下方式促进嵌入:
- 提供嵌入内容的封装,而无需手动创建 HTML 元素。
- 提供点对点通信,以免出现跨帧通信。嵌入 SDK 会使用专用消息通道处理主机网页和嵌入的 Looker 内容之间的跨网域消息传递。
在没有嵌入 SDK 的情况下,您可以使用 JavaScript 事件(例如 dashboard:run:start
或 page:changed
,如嵌入式 JavaScript 事件文档页面中所述)来调用或响应嵌入式 Looker 内容中的事件。使用 JavaScript 事件嵌入 Looker 内容的开发者必须创建 HTML 元素来容纳嵌入的内容,并依赖于窗口广播事件来实现 Web 应用与嵌入内容之间的通信。
请注意,Looker 嵌入 SDK 与 Looker API 和 Looker API SDK 不同:
- Looker 嵌入 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 嵌入 SDK
Looker 嵌入 SDK 使用流畅的接口模式。安装嵌入 SDK 后,您需要构建嵌入内容并连接到嵌入内容。建立连接后,托管应用可以与嵌入的内容互动。
安装嵌入 SDK
您可以通过节点软件包管理器 (NPM) 获取 Looker 的嵌入 SDK 库,网址为 https://www.npmjs.com/package/@looker/embed-sdk。不过,如果您想查看示例代码或演示版,则应改用 Looker 嵌入 SDK 代码库。
如需使用 Looker 嵌入 SDK 代码库安装 Looker 嵌入 SDK,请按以下步骤操作:
- 安装 Node.js(如果尚未安装)。
- 下载或克隆
/looker-open-source/embed-sdk
代码库。 - 在终端窗口中,导航到
/embed-sdk
目录,然后运行以下命令:
npm install
npm start
构建嵌入内容
首先,使用 Looker 服务器的地址和将创建已签名的 Looker 嵌入式登录网址的嵌入应用服务器的端点初始化 SDK。所有嵌入内容都使用这些服务器。对于私密嵌入,请省略签名端点。
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
。如果需要创建新的嵌入会话,则需要按以下方式重新初始化嵌入 SDK:
getEmbedSDK(new LookerEmbedExSDK()).init('looker.example.com', '/auth')
签名网址身份验证端点
本部分不适用于不使用 Cookie 的嵌入。如需了解详情,请参阅无 Cookie 嵌入。
如需使用嵌入 SDK,您必须提供用于处理嵌入网址签名的后端服务。嵌入 SDK 会调用此服务,以生成对请求用户而言唯一的已签名网址。后端进程可以使用嵌入密钥自行生成已签名的嵌入网址,也可以通过调用 Looker Create Signed Embed 网址 API 来生成该网址。手动生成和签署网址可避免调用 Looker API,从而缩短延迟时间。调用 Looker API 所需的代码更少,并且更易于维护。
如需查看用于生成签名网址 createSignedUrl()
的辅助方法的 JavaScript 示例,请参阅 server/utils/auth_utils.ts。其使用方式如下:
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
方法,以配置身份验证端点以允许自定义请求标头和 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 使用调试进行日志记录。您可以使用以下命令在浏览器控制台中启用日志记录:
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 = ''