功能完善的前端通用代理文件 进入全屏
line

前一篇文章有写到form表单+iframe的方式,需要处理跨域的问题,里面用到一个代理文件,例子中给的非常简单,这里补上一个功能比较完善的前端代理文件,能兼容多种参数,多种回调。


前端代理文件:http://www.baidufe.com/proxy

<!DOCTYPE HTML>
<html lang="en-US">
<head>
    <meta charset="UTF-8">
    <title>Proxy Page</title>
    <script type="text/javascript">
    (function(){
        if(top !== self){
            var s = (location.hash || location.search).substr(1).split('&'), //提取参数
                fun = '', // 回调方法 
                isParentScope = false, g, scope, //范围:parent or top
                reg = /[^\w\.]/g,  // 回调方法正则
                args = {},isArgsJson = true,
                domain = "baidufe.com"; // 参数
    
            for(var i=0,l=s.length,item;i<l;i++){
                item = (s[i] || '').split('=');
                if(item[0] === 'fun'){  // 回调方法
                    fun = item[1].replace(reg, '');
                }else if(item[0] === 'parent' && item[1]){ // 标记范围
                    isParentScope = true;
                }else if(item[0] === 'domain' && item[1]){ // 标记范围
                    domain = item[1];
                }else if(item[0] === 'arg'){    // 聚合参数
                    if(isArgsJson) {
                        isArgsJson = false;
                        args = [];
                    }
                    args.push(item[1]);
                }else{  // 参数聚合
                    args[item[0].replace(reg, '')]=(item[1] || '').replace(/[><\'\"\{\}]/g, '');
                }
            }
    
            // 设置scope
            var _setScope = function(isParentScope) {
                if(isParentScope) {
                    scope = g = parent;
                }else{
                    scope = g = top;
                }
            };
    
            // domain校验、设定
            try{
                _setScope(isParentScope);
                // 这一步用来校验是否存在跨域问题
                scope.document;
            }catch(ex){
                // 跨域了,就需要设置domain了
                document.domain = domain ;
                _setScope(isParentScope);
            }
    
            try{
                fun = fun.split('.');
                if(fun[0] === 'window' 
                    || fun[0] === 'document' 
                    || fun[0] === 'location' 
                    || fun[0] === 'alert'
                    || fun[0].indexOf('.alert') > -1){
                }else{
                    // 回调方法拼接
                    for(var i=0,l=fun.length;i<l;i++){
                        if(i<l-1){
                            scope = scope[fun[i]];
                        }
                        g = g[fun[i]];
                    }
    
                    // 方法回调
                    if(isArgsJson){
                        g.call(scope,args);
                    }else{
                        g.apply(scope,args);
                    }
                }
            }catch(e){}
        }
    })();
    </script>
</head>
<body>
        
</body>
</html>



使用例1:在iframe中调用top页面的callback

<iframe src="http://www.baidufe.com/proxy?fun=baidu.editor.callback&arg=errorNo&arg=errorMsg&arg=imgUrl&arg=imgWidth" frameborder="0"></iframe>

上面的代码,在代理文件中最终解释执行为:

<script type="text/javascript">
    top.baidu.editor.callback(errorNo,errorMsg,imgUrl,imgWidth);
</script>


使用例2:iframe中调用parent页面的callback

<iframe src="http://www.baidufe.com/proxy?parent=parent&fun=baidu.editor.callback&arg=errorNo&arg=errorMsg&arg=imgUrl&arg=imgWidth" frameborder="0"></iframe>

上面的代码,在代理文件中最终解释执行为:

<script type="text/javascript">
    parent.baidu.editor.callback(errorNo,errorMsg,imgUrl,imgWidth);
</script>


使用例3:iframe中调用top页面的callback,并且参数为json对象

<iframe src="http://www.baidufe.com/proxy?fun=baidu.editor.callback&errNo=errorNo&errMsg=errorMsg&url=imgUrl&width=imgWidth" frameborder="0"></iframe>

上面的代码,在代理文件中最终解释执行为:

<script type="text/javascript">
    top.baidu.editor.callback({
        errNo : errorNo,
        errMsg : errorMsg,
        url : imgUrl,
        width : imgWidth
    });
</script>


使用例4:主页面已设置了document.domain,如:baidufe.com

<iframe src="http://www.baidufe.com/proxy?fun=baidu.editor.callback&arg=errorNo&domain=baidufe.com" frameborder="0"></iframe>

上面的代码最终解释执行为:

<script type="text/javascript">
    // 强制使得当前代理页面的domain与主页面相同
    document.domain = "baidufe.com";
   
    top.baidu.editor.callback(errorNo);
</script>
阿里巴巴-钉钉-开放平台,能力开放&开发者运营岗位招聘中, 期待你的加入!
钉钉开放,让应用开发更简单
充分开放,是钉钉的重要方向!除致力于为开发者打造丰富的开放API, 更易接入的场景化能力包, 完备的应用开发工具之外, 还需要持续构建开放能力的布道、开发者生态运营体系,包括培训、沙龙、大会、社区合作等等。业务在快速发展,我们也还需要更多优秀的小伙伴加入!

评论区域

line