百度统计失效,referrer背锅了

简介: 前段时间遇到一个问题,就是我的个人网站需要接入第三方百度统计,因为我的文章图片有来自第三方微信后台上传的文章,所以使用<meta name="referrer" content="no-referrer">解决图片访问403的问题,但是此时这个导致我百度统计失效了,于是去查询了一下referrer这个特性。

前段时间遇到一个问题,就是我的个人网站需要接入第三方百度统计,因为我的文章图片有来自第三方微信后台上传的文章,所以使用解决图片访问403的问题,但是此时这个导致我百度统计失效了,于是去查询了一下referrer这个特性。


正文开始...


referrer


这个主要主要是来防护CORS跨站请求伪造的一个标识,对于来源于自身服务器,会默认在请求头中带入refer信息


什么意思,具体看下下面


当我们在html的header中使用

640 (12).png

请求头的General


Referrer Policy: no-referrer

request中整个Referer信息会被删除


如果我们没有加meta标签no-referrer


640 (13).png

那么此时你会发现默认请求头里是


Status Code: 200 OK
Referrer Policy: strict-origin-when-cross-origin

然后请求头request-header里面就会携带了Referer


Referer: http://localhost:8080/

关于referrer的更多信息可以参考http referer策略[1]


我的网站需要不带referrer,因为微信图片如果带了当前站点的referrer就会有问题,所以此时怎么加上百度统计代码呢?


由于最初是这样加入统计的


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="referrer" content="no-referrer" />
    <title>js执行顺序</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <h1>js执行顺序</h1>
    </div>
    <script src="https://hm.baidu.com/hm.js?c7002d193ba43df9317b7fc847709213"></script>
  </body>
</html>

这样的做法是我们通用的方式,就是script脚本放入body中,但是这样会导致百度统计不到,因为meta中已经使用no-referrer了,那怎么办呢?我网页中又需要加no-referrer,不加这个,会导致第三方图片显示不出来。


页面渲染


此时我们需要了解另外一个知识,就是浏览器页面是怎么渲染的


我们写一段测试代码


<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- <meta name="referrer" content="no-referrer" /> -->
    <title>js执行顺序</title>
    <script>
      alert(111);
    </script>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <h1>js执行顺序</h1>
    </div>
    <script src="https://hm.baidu.com/hm.js?c7002d193ba43df9317b7fc847709213"></script>
  </body>

html页面渲染是根据标签顺序同步渲染的,而且script标签会阻塞Dom的渲染

640 (14).png

此时你会看到页面弹框,但是html内容并没有完全渲染出来


当我确认弹框后,页面才显示出来


640 (15).png

我们在header中加入一行css代码


<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- <meta name="referrer" content="no-referrer" /> -->
    <title>js执行顺序</title>
    <style>
      body {
        background-color: red;
      }
    </style>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <h1>js执行顺序</h1>
    </div>
    <script>
      alert(111);
    </script>
    <script src="https://hm.baidu.com/hm.js?c7002d193ba43df9317b7fc847709213"></script>
  </body>

我们会发现,页面先绘制成了红色,然后再执行script脚本,最后页面内容显示出来了


640 (16).png

html标签会按照顺序执行,背景先是变成了红色,然后内容没有立即显示出来,执行script脚本后,才显示了页面内容,这就证明了js会阻塞页面的解析,所以在文章开头,我们要设置referrer,那么我们先执行script统计脚本,然后再设置meta


<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://hm.baidu.com/hm.js?c7002d193ba43df9317b7fc847709213"></script>
    <meta name="referrer" content="no-referrer" />
    <title>js执行顺序</title>
    <style>
      body {
        background-color: red;
      }
    </style>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
    </style>
  </head>

所以我们看到百度统计脚本是正常默认的,但是其他基本就是no-referrer

917143305ffe74293db7c1c31a5000bb.png

其他脚本,因为header设置了meta

21d25471e071e98e0321b219a59882c5.png

所以解决百度统计代码失效的办法就是在设置meta之前执行就行


CSS会阻塞页面解析吗


在以前面试中,就曾经有问到这个问题,css到底会不会阻塞dom的解析,这时常是一个令人模糊的问题


举个例子证实一下自己的猜想


新建一个index.html


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>js执行顺序</title>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <body>
    <div class="app">hello word</div>
  </body>
</html>

然后我引入index.css


我在index.css写入测试代码


.app {
  background-color: red;
}
aaa

你会发现,我在css文件中写入了一段非css的代码


但是页面依旧能够正常渲染

715e48362096a552864358541647af34.png

所以从以上可以证明,css并不会阻塞是dom解析dom解析css渲染是并行的,css负责渲染标签样式,html只是负责解析内容标签,css渲染html解析主要是在GUI线程里面,GUI线程主要是构建DOM Tree,Style Tree,Render Tree布局以及绘制。


JS是单线程的


我们经常会在面试中被问到JS为什么是单线程的,有时会被问得哑口无言。


我们想想JS祖师爷在设计这门语言肯定有其初衷和取舍,浏览器是多进程的,浏览器的每一个窗口就是一个进程,而进程之间都应该是互相独立的,而每一个进程里面的线程是独立,所以js设计时就是单线程的,每个线程之间互不影响


所以JS设计就是单线程的,通常来讲为了弥补单线程的缺陷,所以有了同步任务与异步任务的设计,在浏览器渲染页面,解析dom Tree,绘制css tree,通常在主线程执行栈中优先执行同步任务,主线程执行栈执行完了,然后再执行异步任务,异步任务主要会进入队列中,遵循先进先出原则,直到队列执行完毕为止。


css会阻塞js执行吗?


我们做个实验,在style标签前后都引入一段js执行


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- <meta name="referrer" content="no-referrer" /> -->
    <title>js执行顺序</title>
    <script>
      var start = new Date().getTime();
      console.log("before css");
    </script>
    <link rel="stylesheet" href="./index.css" />
    <!-- <link
      href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.0/css/bootstrap.css"
      rel="stylesheet"
    /> -->
    <script>
      var end = new Date().getTime();
      console.log(end - start, "difftime");
      console.log("after css");
    </script>
  </head>
  <body>
    <div class="app">hello word</div>
    <script>
      const app = document.getElementsByClassName("app")[0];
      app.style.backgroundColor = "green";
    </script>
  </body>
</html>

引入index.css

450026d0ba1d52376ae3f80fcdd8d374.png

引入bootstrap.css

5411c039ca9ae3d5ce0bd9853f457eec.png

我们引入bootstrap.css与引入我们自己的index.css,自此你会发现,最后执行的时间很明显,引入bootstrap的css打印的时间差明显是要大于体积小的css的


所以css是会阻塞js的执行的


但是一般情况,我们不会这么干,一般都会在header中引入css,在body结束标签引入脚本


也就大概会是下面这样


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div id="app"></div>
    <script>
        console.log('hello')
    </script>
</body>
</html>


总结


  • 当你百度统计失效时,如果网站meta使用了no-referrer,如果是在统计脚本之前执行,那么此时需要先执行统计脚本,然后再设置meta
  • js会阻塞dom tree解析,css不会阻塞dom tree解析,css只会影响dom tree的绘制
  • css的加载是会阻塞js的运行的,css体积越小影响越小
  • 外部资源的最佳方式,header引入外链css,body结束标签引入script脚本
  • 本文示例code example[2]
相关文章
|
前端开发 JavaScript API
使用 JavaScript 检测系统主题色
使用 JavaScript 检测系统主题色
625 0
|
SQL 运维 关系型数据库
使用Binlog日志恢复误删的MySQL数据
今天文章的主题是如何使用Mysql内置的Binlog日志对误删的数据进行恢复,读完本文,你能够了解到: MySQL的binlog日志是什么?通常是用来干什么的? 模拟一次误删数据的操作,并且使用binlog日志恢复误删的数据。
1892 1
|
3月前
|
JSON 供应链 API
商品条码查询 API 实战指南:掌握商品“唯一身份标识”
商品条码查询API简介:基于1974年诞生的条码技术,该API通过输入13/14位条码,快速获取商品基本信息(名称、品牌、规格等)和成分信息(营养成分、配料表等)。其核心功能包括商品条码查询接口与成分查询接口,广泛应用于零售、电商、物流及健康饮食等领域。支持HTTP POST请求,提供便捷的代码调用示例。作为数字化转型的重要工具,它不仅方便消费者查询商品详情,还助力商家优化库存管理与销售流程,提升运营效率。
572 3
|
机器学习/深度学习 算法 PyTorch
PyTorch Lightning:简化深度学习研究与开发
【8月更文第27天】PyTorch Lightning 是一个用于简化 PyTorch 开发流程的轻量级封装库。它的目标是让研究人员和开发者能够更加专注于算法和模型的设计,而不是被训练循环和各种低级细节所困扰。通过使用 PyTorch Lightning,开发者可以更容易地进行实验、调试和复现结果,从而加速研究与开发的过程。
421 1
|
SQL 关系型数据库 数据库
17. Python 数据库操作之MySQL和SQLite实例
17. Python 数据库操作之MySQL和SQLite实例
424 2
|
缓存 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
2150 0
|
机器学习/深度学习 存储 人工智能
ONNX 与安全:保护模型免受攻击
【8月更文第27天】随着人工智能和机器学习模型的应用越来越广泛,模型的安全性也成为了人们关注的重点。Open Neural Network Exchange (ONNX) 作为一种开放的标准格式,不仅可以促进不同框架之间的模型共享,还面临着如何保护模型不被恶意攻击的风险。本文将探讨 ONNX 在模型安全方面的考虑,以及如何利用 ONNX 和其他技术来保护模型免受攻击。
565 4
|
SQL 测试技术 数据库
Flask与SQLAlchemy的神秘力量:如何让你的数据库飞起来?
【8月更文挑战第31天】在现代Web开发中,Flask和SQLAlchemy是热门技术栈,前者是轻量级Web框架,后者为强大的ORM库。本文介绍如何在Flask项目中集成SQLAlchemy,通过示例展示数据库操作方法,并分享最佳实践,如熟悉ORM、编写测试及适度使用SQL语句,以提升开发效率和代码质量。
472 0
|
缓存 Kubernetes 数据库
大厂面试必问:如何设计一个扛高并发的系统?
高并发系统是指:在短时间内同时有大量用户请求访问系统,需要系统能够快速、稳定地响应这些请求。本文将讲述如何设计一个扛高并发的系统。
|
运维 关系型数据库 Linux
常用的网站建站面板有哪些?网站运维面板汇总
常用的网站建站面板有哪些?网站运维面板汇总
常用的网站建站面板有哪些?网站运维面板汇总