[前端][fmui]浙政钉iframe跨域加载fmui页面相关问题

问题1

iframe跨域下加载fmui页面,涉及iframe中的ejs相关API的调用需要通讯到父页面触发调用。此处使用pipeline作为通讯工具。

1.需要iframe页面:

jsboot.js中检查引用:

  • 通讯sdk:js/libs/pipeline.min.js

  • 拦截ejssdk: js/libs/ejs.frame.js(引用顺序在ejs.js之后加载。ejs版本要求>=4.2.1,可单独更新ejs.js)

cssboot.js中增加配置:

/**
* 在iframe中是否使用ejs拦截器冒泡至父级页面
* 只有这个开启后,使用ejs拦截器通过PipeLine冒泡至父级页面,使用父级页面的ejs方法
*/
exports.isEJSInterceptors = 1;

2.父页面需要:

pipeline初始化:

  • 引用通讯sdk:js/libs/pipeline.min.js

  • 页面实现:

window.Pipeline = Pipeline;
// 通讯触发ejs函数
window.pipeiEJSAPI = function (options) {
    if (options._type) {
        var _type = options._type;
        var uuid = options.uuid;
        var targetApi = ejs;
        _type = _type.split('.');
        while (_type.length > 0) {
            try {
                targetApi = targetApi[_type.splice(0, 1)];
            } catch (error) {
                console.error(error, 'pipeLine触发EJS-API失败');
            }
        }

        if (targetApi) {
            var controlId = options._controlId;
            var iframes = document.querySelectorAll('iframe');
            var pipeParent = null;
            options.success = function (rtn) {
                if (iframes.length == 1) {
                    pipeParent = new Pipeline(iframes[0].contentWindow);
                    pipeParent && pipeParent.exec('dispatch_' + controlId + uuid, rtn);
                } else if (iframes.length > 1) {
                    for (let i = 0; i < iframes.length; i++) {
                        const frame = iframes[i];
                        pipeParent = new Pipeline(frame.contentWindow);
                        pipeParent && pipeParent.target['dispatch_' + controlId + uuid] && pipeParent.exec('dispatch_' + controlId + uuid, rtn);
                    }
                }
            }
            targetApi(options)
        }
    }
};

// 拦截ejssdk中需要注意,触发的page.open与page.close需要去触发父页面的dd相关API,父页面实现:
window.pageOpen = function (args) {
    var options = null;

    try {
        options = JSON.parse(args);
    } catch (e) {
        options = args;
    }
    dd.openLink({
        url: options.pageUrl,
    });
};
window.closeOpen = function () {
    dd.closePage();
};

问题2

在浙政钉加载的非iframe的fmui页面部分需要使用浙政钉相关API。

jsboot.js中加载浙政钉jssdk:

154行:arr.push('//g.alicdn.com/gdt/jsapi/1.9.4/index.js');

例如页面触发关闭页面,可使用os判断:

if (ejs.os.ddGov) {
    dd.closePage();
} else {
    // xxx
}

问题3

浙政钉iframe加载的页面在iOS中无法使用ejs.storage.getItem(localStorage)获取数据,在iframe中获取其他页面存的值。存取数据需要使用cookie存取。

问题5

fmui表单页触发的选人样式异常,由于被表单中的其他css样式覆盖导致冲突,需要页面中重新定义:

.ejs-select-wrapper .mui-checkbox.mui-left span {
    float: none;
    display: inline-block;
    width: 50px;
    height: 50px;
    padding: initial;
    line-height: 50px;
    font-family: initial;
}

问题4

iframe中拼接的预览地址会由父页面打开,如果是相对路径的地址,需要拼接完整路径。

注意iOS端打开的路径中不能有中文,或者使用encodeURIComponent()编码中文字符。

上述提到的相关资源zip附件:

code.zip

最后更新时间::
贡献者: 吴松泽