还在苦苦敲代码开发APP?你out啦! 试试积木搭建APP吧~

Discuz与phpsso整合时无法同步登录:通过js load 另一个 script 文件导致的问题,phpsso document.write 没有执行

来源:清泛原创     2020-09-05 13:28:34    人气:     我有话说( 0 人参与)

在 web 开发中,出于跨域同步、远程调用等目的,经常需要在网页中通过 script 加载另一段远程 script。最常用最简单的方法就是直接用 document write 输出加载脚本的 HTML

在 web 开发中,出于跨域同步、远程调用等目的,经常需要在网页中通过 script 加载另一段远程 script。

最常用最简单的方法就是直接用 document.write 输出加载脚本的 HTML,如下:

document.write('<script src="http://somehost/path/to/script.js" type="text/script"></' + 'script>');

通常来说用这个方法是没有什么问题的,但是最近在帮人分析整合 phpcms 与 discuzx 同步登录时,发现在 discuzx 登录后无论如何也没能让 phpcms 同步登录。

原因是 dz 的登录采用的是 ajax 方式,ucenter 返回的同步代码就是用上面方法向所有 APP 发起一次 JS 请求模拟登录。phpcms 自身又有一套 phpsso 的单点登录体系,它收到请求后又需要分发给更多采用 phpsso 的 APP,于是它又生成一堆如上方法的 script 输出给最终用户。

但到了最终用户这儿,由于是 ajax 异步加载的,大概算是 BUG,再次输出的 document.write(‘<script..></script>’) 不执行,造成无法同步。

目前的解决方法是在第二次需要加载 js 请求时,换用以下方式:

var s = document.createElement('script');
s.setAttribute("type","text/javascript");
s.setAttribute("src", "http://somehost/path/to/script.js");
document.body.appendChild(s);

顺便提一下,曾经看到过文章说用 document.body.appendChild 在 IE 下有时会卡死,建议改用:

document.getElementsByTagName("head")[0].appendChild(s);

//解决二次<script>不执行的问题
function format_dom($urls) {
        $output = 'var s = document.createElement("script");s.setAttribute("type","text/javascript");';
        foreach($urls AS $url) {
                $output .= 's.setAttribute("src", "'.addslashes(str_replace(array("\r", "\n"), array('', ''), $url)).'");document.getElementsByTagName("head")[0].appendChild(s);';
        }
        return $output;
}

OK.

注:本文为本站或本站会员原创优质内容,版权属于原作者及清泛网所有,
欢迎转载,转载时须注明版权并添加来源链接,谢谢合作! (编辑:admin)
分享到: