• IE下使用location对象有时会出现“没有权限”的错误


    http://jadyyang.blog.sohu.com/145340845.html

    ————————————————————————————————————————————————————————————————

    白社会里有自己的PV系统,同时也在使用sohu统一的PV系统,但数据显示白社会的PV数总是比统一的少。如果从发送先后顺序上来讲,白社会的在 统一的之前,理论上应该更多才对。原因找了很多,包括代码实现方法、加载机制、加载顺序、加载内容、南北方等,做了很多测试都没有发现问题的根源。其中我 们使用了一个我们认为最好的发送形式,在页面的header上直接输出一段js,其直接发送pv代码;而sohu统一的代码放在页面的最尾部,而且是 0.5秒后去加载这个pv.js,加载完之后再发送pv(统一的代码一直是这样的发送形式)。即使这样,很多页面的pv数还是比统一的少了10%,很多次 我都认为上帝是真的存在的。之前也考虑过是否是js写的有问题,出错了导致发送不出来,但是发送的代码实在是太简单了。

        最终我们做了一个测试,很土的方法,在发送PV的地方,加入了很多变量,用于检测代码执行到了哪一步,然后在页面最尾部把这些信息发送到服务器端,看看这 么简单的js哪里出问题了。在最终的log中,终于发现了蛛丝马迹。首先是有问题的那些记录,都是ie,其中ie6占据了90%,ie7占据了将近 10%,只有很少量的是ie8(但浏览器额使用记录上ie6:ie7:ie8应该是4:2:4);这些ie6绝大部分都是xp sp2操作系统;发送PV的方法确实会意外中断。

        于是又增加了一些检测,在pv方法上加了一个try catch,然后把错误信息记录下来。日志上显示,发生错误都是一个原因:没有权限(Permission denied)。从网上查了一下,没有权限实在是一个太常见的提示,微软自己都提供了很多更新来解决本不应该出现的“没有权限”问题。很难讲那些10%的 用户是没有安装哪个补丁导致的问题。

        PV代码很简单,如下:

        (function() {
       
        var a = [], n = document.createElement('script');
            a.push('url=' + encodeURIComponent(location.href));
            a.push('referrer=' + encodeURIComponent(document.referrer));
            n.src = '....pv.gif';
            document.getElementsByTagName('head')[0].appendChild(n);
        })();
        最有可能没有权限的代码就是location,因为之前也遇到过跨域时使用location提示没有权限的问题,因此缩小了范围,把代码改成了:
        (function() {
       
        var a = [], n = document.createElement('script');
            try {
                a.push('url=' + encodeURIComponent(location.href));
            } catch (e) {
                setTimeout(arguments.callee, 0);
                return;
            }
            a.push('referrer=' + encodeURIComponent(document.referrer));
            n.src = '....pv.gif';
            document.getElementsByTagName('head')[0].appendChild(n);
        })();
        这 样修改,数据正常了,问题解决了,但缺没有合理的解释,为啥这样使用location会提示没有权限。可能我们的代码有些特殊,上面这段js是放在一个 script标签上,这个标签的最开始还有一段别的代码(当然也很简单),其中会设置一下document.domain,但是设置的 document.domain就是当前的这个域,而且这个标签放在head标签的最开始,没有什么iframe和 script标签,因此也不会出现多重设置域的问题,理论上也不会出错。现在的整个片段是这样的:
    <head>
    <script type="text/javascript">
        document.domain = 'bai.sohu.com';
        ...  //  简单代码

        (function() {
       
        var a = [], n = document.createElement('script');
            try {
                a.push('url=' + encodeURIComponent(location.href));
            } catch (e) {
                setTimeout(arguments.callee, 0);
                return;
            }
            a.push('referrer=' + encodeURIComponent(document.referrer));
            n.src = '....pv.gif';
            document.getElementsByTagName('head')[0].appendChild(n);
        })();
    </script>

        这是啥问题?只能说这是ie的bug,成因为:
        1. 代码都在一个script中,并且在一个队列中执行
        2. 之前会设置document.domain,并且等于当前的域
        3. 后面的代码会使用location对象
        如果具备这些条件,那在某些ie下,会报“没有权限”的错误。

        有两个解决方法:
        1. 使用location时进行try catch,如果发现是没有权限的问题,可以把代码放到下一个执行队列中(setTimeout)
        2. 直接放到两个独立的script标签上,一个上设置document.domain,一个是使用location,这样应该也能解决(是根据上面的理论得出,
    没有经过测试

  • 相关阅读:
    面向对象(二)-特性
    面向对象(一)-初步认识
    函数(十)-内置模块
    函数(九)-包与模块
    函数(八)-闭包与装饰器
    函数(七)-嵌套作用域
    函数(六)-匿名函数
    CSS阴影效果(Box-shadow)用法趣味讲解
    css 实现div内显示两行或三行,超出部分用省略号显示
    js基础知识(一)--截取字符串
  • 原文地址:https://www.cnblogs.com/cuizhf/p/3561365.html
Copyright © 2020-2023  润新知