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,这样应该也能解决(是根据上面的理论得出,
没有经过测试

IE下使用location对象有时会出现“没有权限”的错误的更多相关文章

  1. 使用Location对象查询字符串参数

    location是BOM中最有用的对象之一: 1.它提供了与当前窗口中加载的文档有关的信息: 2.他还提供了一些导航功能. location对象的属性有: hash, host, hostname, ...

  2. BOM之location对象

    定义 location提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能.location是一个很特别的对象,因为它既是window对象的属性,也是document对象的属性.换句话说,wi ...

  3. Location对象、History对象

    Location对象: Window对象的location属性引用的是Location对象,它表示窗口中当前显示的内容的URL,Document对象的location属性也引用Location对象,w ...

  4. JavaScript window.location对象

    JavaScript window.location对象   示例 注意 方法 经常使用window.location,它的结构总是记不住,简单梳理下,方便以后查询. 示例 URL:http://b. ...

  5. Javascript的location对象

    JavaScript window.location对象 示例 注意 方法 经常使用window.location,它的结构总是记不住,简单梳理下,方便以后查询. 示例 URL:http://b.a. ...

  6. Js之Location对象

    Window对象的location属性引用的是Location对象,它表示该窗口中当前显示的文档的URL,并定义了方法来使窗口载入新的文档.Document对象的location属性也引用到Locat ...

  7. javascript深入之location对象和history对象

    浏览器的location 和history对象: 一.location对象: 1>location.reload() 相当于按浏览器上的“刷新”(IE)或“Reload”(Netscape)键. ...

  8. location对象的属性和方法应用(解析URL)

    本文将与大家分享下location对象使用属性和方法来解析URL的实例,感兴趣的朋友可以参考下,希望对你有所帮助   location对象提供了很多属性和方法用来解析URL. 复制代码代码如下: &l ...

  9. History对象和location对象

    history对象 History对象包含用户在浏览器窗口中访问过的url.不是所有浏览器都支持该对象. 属性length   返回浏览器历史列表中的URL数量. 方法:back() 加载histor ...

随机推荐

  1. 教你如何搭建vue项目

    笔者工作也有一些时间,需要用vue写项目时也总是项目组长已经把项目搭建好了, 偶尔心血来潮想试着自己搭建一个vue项目 我们搭建vue项目呢主要是用到了vue-cli来搭建,但是前提是必须要已经安装好 ...

  2. vue - package.json

    描述:包管理信息(npm || yarn) npm 和 yarn 站在了对立面. 不过我还是首推 yarn. 

  3. vue - webpack.dev.conf.js

    描述:开发时的配置.(配置开发时的一些操作) 例如这里,是否自动打开浏览器(默认true) 'use strict' // build/util.js const utils = require('. ...

  4. Entity Framework底层操作封装V2版本号(1)

    由于同志们一直给我提建议说.曾经发的版本号有问题.所以经过了我这一年多的使用和扩展,如今方法基本稳定了. 如今贴出来给大家使用: 首先上场的是数据库操作层: using System; using S ...

  5. SVN:This client is too old to work with working copy…解决方法

    昨天升级了一下苹果系统到10.10,扁平化确实不错,高兴之余多少有些不快.我的svn出现故障,总是提示我  SVN:This client is too old to work with workin ...

  6. Aeroo Reports Linux server

    This article covers installation process for Aeroo reporting engine on Linux servers. If you find th ...

  7. 使用python在WEB页面上生成EXCEL文件

    来自:http://blog.sina.com.cn/s/blog_5d18f85f0101bxo7.html 近日写的一个程序需要在WEB服务器上生成EXCEL文件供用户下载,研究了一下找到了以下比 ...

  8. STL源码剖析(deque)

    deque是一个双向开口的容器,在头尾两端进行元素的插入跟删除操作都有理想的时间复杂度. deque使用的是分段连续线性空间,它维护一个指针数组(T** map),其中每个指针指向一块连续线性空间. ...

  9. C/C++ 编程计算2的100万次方(m的n次方),超长结果输出文件

    #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string> ...

  10. Error: could not open `C:\Program Files\Java\jre6\lib\i386\jvm.cfg')

    前些日子装了个jdk7试了试,后来做项目需要换成jdk6,安装完jdk6,设置完环境变量后出现问题.运行java -version出现Error: could not open `C:\Program ...