跳到主要内容

kaleidr.js 加载器

kaleidr.js 是所有 Kaleidr 嵌入功能的入口脚本。它定义全局对象 window.Kaleidr 和自定义元素 <kaleidr-map>。脚本体积小,不包含地图库或产品代码。挂载产品时,它从同一 CDN 加载该产品的包并传入选项。

<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>

没有 npm 包。SDK 只能通过 script 标签加载。React、Next.js、Vue 和 TypeScript 用法请参阅框架集成。

加载脚本​

问题答案
标签放在哪里?任意位置。<kaleidr-map> 元素无论位于标签前后都能挂载。
何时调用 Kaleidr.mount?脚本执行后。对于普通 <script src> 标签,页面中后续脚本即可调用。
能使用 async 或 defer 吗?元素可以。调用 Kaleidr.mount 时须等待标签的 load 事件,因为此前 window.Kaleidr 尚未定义。
加载几次?每页一次。
能添加 integrity 吗?不能。文件会在原路径更新,固定哈希将在下一次发布时失效。参见 CDN 版本管理。
能在服务器上运行吗?不能,需要 window 和 document。服务端渲染的应用应仅在浏览器中加载。

使用 async 加载脚本,并在加载后挂载:

<div id="map" style="height:480px"></div>
<script>
const s = document.createElement('script');
s.src = 'https://cdn.kaleidr.com/embed/v1/kaleidr.js';
s.async = true;
s.onload = () => {
Kaleidr.mount('#map', { product: 'viewer', shareId: 'YOUR_MAP_ID' });
};
document.head.appendChild(s);
</script>

window.Kaleidr​

成员说明
Kaleidr.mount(target, options)将产品挂载到元素中并返回操作句柄。
Kaleidr.init()初始化文档中已有的 <kaleidr-map> 元素,通常无需手动调用。
Kaleidr.enable(on)开启或关闭后续挂载。
Kaleidr.version加载器版本字符串,用于诊断。

Kaleidr.mount(target, options)​

const handle = Kaleidr.mount('#chat', {
product: 'chat',
publishableKey: 'kld_pk_live_…',
map: myMap,
contained: true,
});
参数类型说明
targetCSS 选择器或 HTMLElement挂载目标。选择器通过 document.querySelector 仅解析一次。
options对象必填。参见选项。

返回一个操作句柄。

运行行为:

  • 立即返回。 会话交换和产品包加载在后台进行。此期间的句柄调用会排队,在产品就绪后依次执行。对于 Viewer 和 Tile,就是 iframe 内地图报告就绪之时,因此能在调用 setCamera 之前执行 mount,下一行的设置仍有效。
  • 挂载失败不会抛异常。 找不到目标、加载包失败、会话被拒绝或 ID 无效时,控制台记录含 [kaleidr:<product>] 的错误。仍会返回句柄,但其方法不执行操作。唯一会抛异常的是缺少选项对象的 Kaleidr.mount('#map'),它会抛出 TypeError。
  • 不向代码反馈结果。 没有可等待的 Promise 或回调。参见判断挂载是否成功。
  • 每个目标只允许一个挂载。 再次挂载前先调用原句柄的 handle.destroy()。即使首次挂载尚在加载,销毁后在同一元素重新挂载也安全;已销毁的挂载不会干扰新挂载。

选项​

选项类型默认值适用产品说明
product'chat' | 'viewer' | 'editor' | 'tile'无,必填全部选择挂载的产品。
publishableKey字符串无chat、editor、tile可发布密钥 kld_pk_…。SDK 将其交换为短期会话,仅把会话交给产品。不要传给 Viewer。服务器密钥 (kld_sk_…) 会在请求发送前被拒绝。
shareId字符串无viewer、chatViewer:已发布地图的 ID。无密钥的 Chat:由地图所有者提供聊天服务的已发布地图。
mapId字符串无viewershareId 的别名,仅在没有 shareId 时使用。
styleId字符串组织的默认底图tile、editor例如 kaleidr-morning 的样式 ID,或完整样式 URL。
map运行中的地图实例无chat供助手操控的地图:Mapbox GL JS、MapLibre GL JS、Google Maps 或 Leaflet。参见支持的地图。纯聊天面板可省略。
mapTargetCSS 选择器无chat供助手操作的 Viewer/Tile <kaleidr-map> 元素,用来代替 map。
contained布尔值falsechat将面板停靠到有定位和尺寸的目标内部。默认是在视口左上角的固定悬浮窗口。
lang字符串页面有效的 <html lang>,否则英语chat回答语言,使用 BCP 47 标签,如 en、ko 或 pt-BR。参见聊天语言。
title字符串面板自身标题chat面板标题栏的文本,元素属性为 chat-title。
placeholder字符串面板自身占位文字chat输入框占位提示。
center[longitude, latitude]产品默认值viewer、tile、editor初始中心点。
zoom数值产品默认值viewer、tile、editor初始缩放级别。Viewer/Tile 只有和 center 同时提供才生效。
pitch数值产品默认值viewer、tile、editor初始倾斜角(度)。
bearing数值产品默认值viewer、tile、editor初始旋转角(度)。
theme对象或对象的 JSON 字符串无chat、editorChat:自定义 CSS 属性,如 { '--highlight-color': '#0b5fff' }。Editor:参阅 17 个主题键。非 JSON 字符串会被忽略并警告。
enabled布尔值无全部每次挂载独立控制的启用开关,仅在挂载时读取。
baseURLhttps://cdn.kaleidr.com全部产品包来源。只采用源站,并始终从其 /embed/v1/ 加载。只有基础地址覆盖规则允许的源站才生效;其他值会被忽略并警告。
viewerBaseURLhttps://map-embed.kaleidr.comviewer、tileiframe 的来源,只使用源站。
apiBaseURLhttps://api.kaleidr.com/inference-apichat、editor、tile会话交换和产品请求的 API 地址,必须含 /inference-api;只填写源站会返回 404。
tileBaseURLhttps://tile.kaleidr.comeditor解析样式 ID 的主机。

注意:

  • apiKey 是 publishableKey 已弃用的别名。
  • 四种 …Base 选项用于测试其他部署,生产环境通常不需要。base 只改变包的来源;地图页面、API 和底图主机仍使用 Kaleidr 地址,除非分别覆盖。
  • lang、title 和 placeholder 在挂载时读取,更改它们需要销毁并重新挂载。
  • 产品不使用的选项会静默忽略。

基础地址覆盖规则​

base(选项和元素属性)以及页面全局变量 window.__KALEIDR_EMBED_BASE__ 用于指定产品包的来源。覆盖只在来源属于下列之一时有效:

允许的源站示例
Kaleidr CDNhttps://cdn.kaleidr.com
加载 kaleidr.js 的源站kaleidr.js 从 https://static.example.com 加载,且 base 为 https://static.example.com。
当前页面的源站页面在 https://www.example.com/…,且 base 为 https://www.example.com。

其他值均被忽略。挂载仍继续,包从默认 CDN 加载,同时控制台显示一条警告:

[kaleidr] base "https://other.example.net" is IGNORED — bundles load from https://cdn.kaleidr.com. A base must be the Kaleidr CDN, the origin kaleidr.js was loaded from, or this page's own origin.

页面全局变量必须是字符串,其他类型会被静默跳过。若加载器与包从同一源站提供,自行托管也遵循此规则。

各产品默认摄像机设置:

产品默认视角
viewer地图作者保存的视图。
tile样式默认视图,否则显示全球。
editor中心 [0, 0],缩放 2,倾斜 0,旋转 0。
chat不适用,Chat 不创建地图。

详细说明见各产品页面:Chat、Viewer、Tile、Editor。

操作句柄​

Kaleidr.mount 对所有产品返回结构相同的句柄。

interface KaleidrHandle {
readonly product: 'chat' | 'viewer' | 'editor' | 'tile';
setCamera(camera: {
center?: [number, number]; // [longitude, latitude]
zoom?: number;
pitch?: number;
bearing?: number;
duration?: number; // milliseconds
}): void;
setTheme(theme: string | Record<string, string>): void;
setStyle(style: string): void;
destroy(): void;
}

每个句柄都有全部方法,但具体效果因产品而异:

方法chatviewereditortile
setCamera(camera)警告是是是
setTheme(theme)是警告警告警告
setStyle(style)警告警告警告是
destroy()是是是是

“警告”表示调用无效,并在控制台显示提示。

[kaleidr] setCamera() is not supported on product "chat" — the call is a no-op. See the handle matrix at https://docs.kaleidr.com/sdk/kaleidr-map-element#handle-matrix.

这是 /embed/v1 协议的一部分:不支持的方法不会抛异常。

方法说明:

  • setCamera:未提供的字段保持原值。duration 指定动画时长;省略或设为 0 则立即跳转。Chat 不支持 setCamera,因为它不拥有地图,但助手回答时仍会移动所连接的地图。若需主动移动,请调用地图库自己的 API。
  • setTheme:仅 Chat。接收自定义 CSS 属性对象或其 JSON 字符串。
  • setStyle:仅 Tile。接收样式 ID 或 URL。
  • destroy:移除挂载内容、停止会话续期并清空等待中的调用。重复调用无害。销毁的句柄不能重用,须重新挂载。

调用 mount 后可立即使用句柄。 对 Viewer 和 Tile,地图 iframe 就绪前的 setCamera(Tile 还有 setStyle)调用会按顺序缓存,待地图发出 kaleidr-embed:ready 或首次摄像机位置后执行,最多保留最近 256 次。若 iframe 加载后经过有限等待(通常 10 秒)仍未就绪,缓存的调用仍会发送,并显示一次警告:

[kaleidr] the map frame has not reported ready — calls held for it are sent now, and may reach no map. The frame may be showing an error (an unpublished map, a blocked request).

等待从 iframe 实际加载时开始。视口外尚未加载的 iframe 会继续保留调用。因此无需等待 kaleidr-embed:ready 才能操作句柄。该消息和 kaleidr-embed:error 仍用于判断成功与否,见 Viewer 消息。

句柄没有 ready Promise、on() 方法,也没有 map 或 iframe 成员。

Kaleidr.init()​

初始化调用时文档中所有 <kaleidr-map> 元素。加载器会自动调用;后续插入的元素也会自行挂载,因此很少需要手动调用。重复调用无害。

启用开关​

嵌入默认启用。开关关闭时,Kaleidr.mount 不加载、不发送任何数据,且返回方法均无效的句柄。可用于等待访客同意,或无需修改标记就暂时禁用嵌入。

三种控制方式​

控制作用范围设置方式
页面标志当前页面的所有挂载在希望阻止的挂载之前设置 window.__KALEIDR_EMBED_ENABLED__ = false
Kaleidr.enable()调用后的所有挂载Kaleidr.enable(false)
单次挂载一个挂载选项 enabled: false 或属性 flag="false"

如何决定是否挂载​

每次挂载时,SDK 都读取全部三个控制:

  1. 任一个明确为 false,就阻止挂载。
  2. 否则,只要有一个明确为 true,就继续挂载。
  3. 否则采用默认开启状态。

这会产生三个重要结果:

  • false 只能通过设置它的控制方式解除。 Kaleidr.enable(true) 无法解除单次挂载的 enabled: false,也无法解除设为 false 的页面标志。各控制不能相互覆盖。
  • 仅在挂载时检查。 解除开关不会自动启动此前被阻止的挂载,之后关闭开关也不会卸载现有产品。解除后须重新调用 Kaleidr.mount,或移除并重新插入元素。
  • 页面标志在每次挂载时读取,不只是脚本加载时。因此稍后设置会影响下一次挂载。
阻止来源解除方法
window.__KALEIDR_EMBED_ENABLED__ = false将它设为 true 或删除。
Kaleidr.enable(false)调用 Kaleidr.enable(true),或以 Kaleidr.enable(null) 恢复默认值。
enabled: false 或 flag="false"不带该设置重新挂载。修改已挂载元素的 flag 属性无效。

被阻止时,控制台只显示一条指出控制来源的警告:

[kaleidr] embed is disabled — window.__KALEIDR_EMBED_ENABLED__ is false. Reassigning it releases that lever — Kaleidr.enable() cannot.

可接受的值​

控制值严格按布尔规则解释,以免意外的字符串错误地启用嵌入。

控制视作 true视作 false忽略并警告
window.__KALEIDR_EMBED_ENABLED__truefalse任何非真正布尔值,包括字符串 "true" 和 "false"
Kaleidr.enable(x)无参数、true、"true"、"1"、"yes"、"on"false、0、""、"false"、"0"、"no"、"off"其他字符串、undefined、对象、函数
enabled 选项true、"true"、"1"、"yes"、"on"false、0、""、"false"、"0"、"no"、"off"其他字符串、对象、函数
flag 属性无值的 flag、"true"、"1"、"yes"、"on""false"、"0"、"no"、"off"任何其他值

比较时忽略大小写和首尾空格。从存储中读取时有两个注意事项:

  • Kaleidr.enable(null) 会重置为默认状态,不表示“没有意见”。没有保存值时,localStorage.getItem(key) 返回 null,这恰是访客尚未同意时的状态,所以不要直接传入存储值,先比较:Kaleidr.enable(stored === 'true')。
  • 被忽略的值保持控制原有状态,既不启用也不禁用。

示例:获得同意前阻止嵌入​

本页用页面标志阻止所有嵌入;它适用于加载器运行时自动挂载的元素。访客同意后,通过同一标志解除阻止,再将元素重新插入以触发挂载。

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Consent-gated map</title>
<script>
// A real boolean, set before the loader. A stored string is compared, never passed through.
window.__KALEIDR_EMBED_ENABLED__ =
localStorage.getItem('embeds-consent') === 'true';
</script>
<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
</head>
<body>
<div id="banner">
This page shows an interactive map from Kaleidr.
<button id="accept">Show the map</button>
</div>

<kaleidr-map product="viewer" share-id="YOUR_MAP_ID"
style="display:block; height:480px"></kaleidr-map>

<script>
const banner = document.getElementById('banner');
if (window.__KALEIDR_EMBED_ENABLED__) banner.hidden = true;

document.getElementById('accept').addEventListener('click', () => {
localStorage.setItem('embeds-consent', 'true');
banner.hidden = true;

// 1. Release the lever that held the embeds.
window.__KALEIDR_EMBED_ENABLED__ = true;

// 2. A held element does not mount by itself. Re-insert each one.
document.querySelectorAll('kaleidr-map').forEach((el) => {
const parent = el.parentNode;
const next = el.nextSibling;
el.remove();
parent.insertBefore(el, next);
});
});
</script>
</body>
</html>

同意前,“网络”面板只会显示 kaleidr.js,不会有其他 Kaleidr 产品包、会话请求或 iframe。

如果通过 JavaScript 挂载,则不必使用开关:获得同意前不要调用 Kaleidr.mount。开关主要适合直接写在 HTML 中的元素,或标签管理器、其他团队代码会调用 mount 而你需要控制整页的情况:

Kaleidr.enable(false); // hold every later mount
// …
Kaleidr.enable(true); // release it
const handle = Kaleidr.mount('#map', { product: 'viewer', shareId: 'YOUR_MAP_ID' });

页面全局变量​

全局变量类型读取时间用途
window.__KALEIDR_EMBED_ENABLED__布尔值每次挂载启用开关的页面标志。
window.__KALEIDR_EMBED_BASE__URL 字符串每次挂载自行托管时的产品包来源。只使用源站,且必须满足基础地址覆盖规则。参见 CDN 版本管理。

判断挂载是否成功​

SDK 不向代码提供就绪或失败信号,但可以观察:

产品已加载失败
vieweriframe 发送 kaleidr-embed:ready。iframe 发送 kaleidr-embed:error,或控制台出现 [kaleidr:viewer] 错误。
tileiframe 发送 kaleidr-embed:ready。会话被拒只在控制台显示;绘制失败发送 kaleidr-embed:error。
chat无信号,面板出现在页面中。仅控制台。
editor无信号,编辑器出现在页面中。仅控制台。

这两种消息在 Viewer 消息中有说明。

挂载失败时的情况​

原因表现发送请求?
选择器找不到目标[kaleidr:<product>] mount target not found: <selector>否
元素缺少有效 product[kaleidr] <kaleidr-map> requires product="chat|viewer|editor|tile"否
传入服务器密钥[kaleidr:<product>] Kaleidr: a server key (kld_sk_…) must never be used in the browser — it is a standing secret. Use your publishable key (kld_pk_…) here and keep the server key server-side.否
密钥未知、被撤销或页面来源不允许浏览器对 sessions 报 CORS 错误,随后 [kaleidr:<product>] 请求失败;没有内容显示。是
缺少权限范围、产品限制或套餐不支持[kaleidr:<product>] kaleidr session exchange failed (403);无内容。是
地图加载额度耗尽(tile)或会话请求过多[kaleidr:<product>] kaleidr session exchange failed (429);无内容。是
产品包无法加载[kaleidr:<product>] [kaleidr] failed to load https://cdn.kaleidr.com/embed/v1/<product>.js不适用
Viewer 缺少 ID 或 ID 格式错误[kaleidr:viewer] Kaleidr map: invalid id "" — must match ^[A-Za-z0-9._~-]{1,100}$.否
Editor 缺少密钥[kaleidr:editor] [editor-embed] attach() requires an { apiKey }否
Chat 既没有密钥也没有 shareId面板仍会显示,但每个问题均失败。挂载时不发送
启用开关关闭[kaleidr] embed is disabled — …否

SDK 不显示服务器给出的具体原因。 会话被拒时仅记录 HTTP 状态。原因在响应正文:403/404 的代码在 detail 字段,如 {"detail":"insufficient_scope"};429 的代码在 error 字段,并有 detail 解释。例外是 map_load_quota_exceeded,代码在 detail。在“网络”面板选择 sessions 请求查看响应;若被 CORS 隐藏,请在终端重现请求:

curl -i https://api.kaleidr.com/inference-api/b2b/v1/sdk/sessions \
-H "x-api-key: kld_pk_live_…" \
-H "Origin: https://www.example.com" \
-H "content-type: application/json" \
-d '{"product":"chat"}'
HTTP/2 403
content-type: application/json

{"detail":"origin_not_allowed"}

使用出错页面的实际来源。测试时用 "chat"、"editor" 或 "viewer";成功的 "tile" 交换会计入一次地图加载。所有代码详见错误。

首次会话交换失败后,该挂载不会自动重试。修复原因后重新挂载。

会话交换概要​

对于 Chat、Editor 和 Tile,SDK 不会用可发布密钥直接调用运行时 API,而是先将它换成会话。

  1. 挂载时,SDK 向 POST https://api.kaleidr.com/inference-api/b2b/v1/sdk/sessions 发送请求,携带请求头 x-api-key: <your publishable key> 和正文 {"product":"<product>"}。浏览器添加页面 Origin。
  2. Kaleidr 依次验证:密钥是否可发布;请求是否有来源;如设有允许来源列表,来源是否匹配;密钥和组织套餐是否允许产品;密钥是否含必要的权限范围:Chat 用 ai,Editor 用 design,Tile 用 maps,Viewer 不需要。
  3. 响应为 {"session_token": "…", "expires_in": 900, "product": "…", "basemap_style_id": …}。basemap_style_id 是组织的默认底图,没有则为 null。
  4. 产品在请求中使用绑定了来源与产品的会话令牌。
  5. SDK 在会话到期前 90 秒续期;后台标签页重新显示且会话即将到期时也续期。续期失败则在挂载期间每 30 秒重试。
  6. handle.destroy() 停止续期。

Viewer 不需要会话。使用 shareId 且不提供密钥的已发布地图 Chat,从地图本身而非密钥获取会话。参见已发布地图上的聊天。

请求和响应详见端点。密钥类型、会话及来源白名单的保护范围与局限,请参阅安全模型。

其他控制台消息​

消息含义
[kaleidr] <method>() is not supported on product "<product>" — the call is a no-op. …调用了该产品不支持的句柄方法。
[kaleidr] <method>() IS supported on product "<product>", but this mount did not expose it, so the call did nothing. …浏览器缓存中的产品包比加载器旧,请绕过缓存重新加载。
[kaleidr] the map frame has not reported ready — calls held for it are sent now, and may reach no map. …Viewer/Tile 地图未在句柄规定的等待时间内就绪,缓存的 setCamera、setStyle 已发送,可能无地图接收;请监听 kaleidr-embed:error。
[kaleidr] theme must be an object of CSS tokens, not an array; ignored.theme 是数组。
[kaleidr] theme string must be JSON …; named string themes are not supported. Ignored.theme 字符串不是以 { 开头。
[kaleidr] theme JSON parse failed (…); ignored.theme 是格式错误的 JSON。
[kaleidr] <attribute>="<value>" is not a recognized boolean — the attribute is IGNORED. …flag 或 contained 的值无法识别;消息中会指明 flag="…" 或 contained="…"。
[kaleidr] base "<value>" is IGNORED — bundles load from <origin>. …base 或 window.__KALEIDR_EMBED_BASE__ 指定的来源不符合基础地址覆盖规则,因此使用默认 CDN。
[kaleidr] window.__KALEIDR_EMBED_ENABLED__ must be a boolean; got <type> (…). …页面标志不是布尔值,被忽略。
[kaleidr] Kaleidr.enable(): "<value>" is not a recognized boolean — the value is IGNORED. …Kaleidr.enable 收到无效值。
[kaleidr] enabled: "<value>" is not a recognized boolean — the value is IGNORED. …enabled 挂载选项收到无效值。
[kaleidr] Kaleidr.enable(undefined) is IGNORED and leaves the gate exactly as it was. …Kaleidr.enable 收到 undefined,开关状态不变。
[kaleidr] Kaleidr.enable(null) RESET the gate to the build default, releasing the <value> set earlier. …Kaleidr.enable(null) 清除了之前的设置并恢复默认状态。

尚不提供​

  • npm 包、ES 模块版本或自带类型定义;可从框架集成复制声明。
  • iOS、Android、React Native 或 Flutter 原生 SDK。
  • 句柄上的 ready Promise、事件或回调。
  • 不挂载产品即可调用 API 的 JavaScript 客户端;请在后端使用服务器 API。

相关页面​