页面外部嵌入
此功能可以将在爱速搭制作的页面,快速嵌入到已有业务系统中。采用的是 jssdk 模式,相比 iframe,有更好的用户体验,比如弹框是直接弹出在整个页面而不是只能在 iframe 内部。 此功能整合成本较低,适用于所有前端框架(包括微前端),引入一段 js 代码片段即可完成指定容器(div)的页面渲染。(如果是 React,还可以当成内部组件一样使用。)
js 代码由爱速搭自动生成的,能一键上传到您指定的对象存储(bos、s3 或者 oss)中,然后可以通过 cdn 地址引用。这样您的业务系统在运行时不依赖爱速搭平台渲染页面,稳定性能得到保障。(如果页面里面只是用您业务系统中的内部接口,这个时候运行时是完全脱离了对爱速搭平台的依赖。但是如果页面里面使用了 api 编排,或者数据模型相关接口,则还是会有依赖,不过内置了登录功能,依然可以联通)
简要说明
JSSDK 会生成如下代码,可以看出引入一段 js,然后执行一下 mount 即可完成页面渲染到指定 div 容器。
- script 代码
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>test</title>
8 </head>
9 <body>
10 // 将『{{loderUrl}}』替换为导出的loader文件地址
11 <script src="{{loderUrl}}"></script>
12
13 <div id="root"></div>
14 <
15 <script>
16 // 将『{{pageUrl}}』替换为导出的page文件地址
17 amisLoader.load('{{pageUrl}}', page => {
18 const data = {key: 'value'};
19 page.mount('#root', page.schema, data);
20 });
21 </script>
22 </body>
23</html>
如果是嵌入到 React 框架中,则可以直接使用我们封装好的 React Component,然后当普通组件一样使用即可,如:
1function myComponent() {
2 const pageUrl = '';
3 const data = {};
4
5 return <AisudaPage pageUrl={pageUrl} data={data} />;
6}
AisudaPage 内部自动会加载所需要的资源。
功能使用详情
由于 jssdk 是自动上传到对象存储的,所以需要提前设置对象存储信息,大致流程如图。
功能使用详细介绍:
- 配置对象存储,配置入口如图所示:
- 功能入口:功能的入口在页面的右侧,如图所示:
-
点击导出后,您可以选择当前页面导出的环境类型,路由模式以及请求域名。
- 环境类型:应用的环境类型,默认当前环境。可以选择其他环境,但需要确保当前页面已发布。
- 路由模式:hash 或 browser 模式,属于浏览器的特性,详细信息可查询文档。
- 请求域名:如果在 API 中心配置了请求,可以在这里配置请求域名,修改请求的转发地址,不配置默认爱速搭的域名。
页面成功导出后,会自动生成前端代码,包括 script 代码以及 react 组件示例
- script 代码
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>test</title>
8 </head>
9 <body>
10 // 将『{{loderUrl}}』替换为导出的loader文件地址
11 <script src="{{loderUrl}}"></script>
12
13 <div id="root"></div>
14 <
15 <script>
16 // 将『{{pageUrl}}』替换为导出的page文件地址
17 amisLoader.load('{{pageUrl}}', page => {
18 const data = {key: 'value'};
19 page.mount('#root', page.schema, data);
20 });
21 </script>
22 </body>
23</html>
- react 公共组件代码
1/**
2 * @file common/aisudaPage.tsx
3 */
4
5import * as React from 'react';
6
7interface AisudaPageProps {
8 /**
9 * 加载器 Url
10 */
11 loaderUrl: string;
12
13 /** 页面 Url */
14 pageUrl: string;
15
16 data?: any;
17}
18
19export class AisudaPage extends React.Component<AisudaPageProps> {
20 static defaultProps: Pick<AisudaPageProps, 'loaderUrl'> = {
21 // 将『{{loderUrl}}』替换为导出的loader文件地址
22 loaderUrl: '{{loaderUrl}}'
23 };
24
25 rootDom = React.createRef<HTMLDivElement>();
26 unmounted = false;
27 currentPage: any = null;
28
29 componentDidMount() {
30 this.loadAMISLoader(this.props.loaderUrl, loader => {
31 if (this.unmounted) {
32 return;
33 }
34
35 loader.load(this.props.pageUrl, (page: any) => {
36 // 替换请求域名
37 const data = {
38 AISUDA_HOST: 'http://localhost.aisuda.bce.baidu.com:8089',
39 ...this.props.data
40 };
41 this.currentPage = page;
42 this.rootDom.current &&
43 !this.unmounted &&
44 page.mount(this.rootDom.current, page.schema, data);
45 });
46 });
47 }
48
49 componentDidUpdate() {
50 this.currentPage?.updateProps({
51 data: this.props.data
52 });
53 }
54
55 componentWillUnmount() {
56 this.unmounted = true;
57 this.currentPage?.unmount();
58 }
59
60 loadAMISLoader(url: string, callback?: (loader: any) => void) {
61 if ((window as any).amisLoader) {
62 callback?.((window as any).amisLoader);
63 return;
64 }
65
66 const script = document.createElement('script');
67 script.setAttribute('type', 'text/javascript');
68 script.onload = () => {
69 callback?.((window as any).amisLoader);
70 };
71 script.setAttribute('src', url);
72
73 document.body.appendChild(script);
74 }
75
76 render() {
77 return <div ref={this.rootDom}>Loading...</div>;
78 }
79}
- react 组件示例代码
1/**
2 * @file jssdkReactComp.tsx
3 *
4 */
5
6import * as React from 'react';
7import {AisudaPage} from '@common/aisudaPage';
8
9export default function TestComp() {
10 // 将『{{pageUrl}}』替换为导出的page文件地址
11 const pageUrl = '{{pageUrl}}';
12 const data = {customData: 'this is custom data'};
13
14 return (
15 <>
16 <AisudaPage pageUrl={pageUrl} data={data} />
17 </>
18 );
19}
- 其他框架使用
该功能提供了两个核心文件:loaderUrl
和 pageUrl
,加载 loaderUrl
后会在全局挂载一个 amisLoader
对象,然后就可以通过 amisLoader.load
加载对应的页面。
使用文档
amisLoader.load
方法接受两个参数,参数说明如下:
- pageSrc: 类型为 string,页面信息存储的地址,如:http://bucket.endpoint/key.js
- 回调函数:回调函数接受一个参数 page,类型为
PageProsp
,具体内容见PageProsp
PageProsp 中的参数以及方法说明如下:
- schema:页面的 schema 信息
- mount:挂载页面的方法,第一个参数可以是 ID 选择器,也可以是 dom 节点(ref);第二个参数是页面的 schema,既
PageProsp.schema
;第三个参数是页面需要的数据 - unmount:卸载页面的方法,第一个参数可以是 ID 选择器,也可以是 dom 节点(ref)。
- updateProps: 更新页面数据的方法。
其他说明
-
如果您使用了 API 中心的请求,且导出后请求域名为爱速搭平台,既爱速搭平台代理您的请求,需要进行以下设置:
- 您的应用必须是 https,并且确保有 header X-Forwarded-Proto: https 透传到实例
- 配置 docker env ISUDA_COOKIE_SAMESITE 为 none
- 应用设置/接口 中将使用 jssdk 的站点 host 信息填入到允许跨域站点列表中
- 我们提供了一个通知功能,您可以在 API 中心新增一个接口,然后在 应用设置/接口 中配置 jssdk 通知接口,配置之后,当您导出页面之后,点击 发送消息通知,我们会将您当前导出的页面
pageurl
、loaderUrl
等信息发送给您配置的接口。