ssr出现Hydration error的处理方法
线上出现了Hydration error,而本地用ssr跑时页面打不开,express端报undefined。去线上的pm2看日志,是isWeixin()这个方法报windows undefined. 原来还是ssr的bug,之前修改时在server端调用了isWeixin()而直接使用了windows对象。看来线上如果出现了Hydration error,首先是查看后端有没有问题。
如果后端没有发生错误,这几个点注意下:
浏览器console报:Hydration completed but contains mismatches
1. <v-if> 的使用:根据isBigScreen来动态展示页面,用<v-if="isBigScreen"> 来判断,isBigScreen默认=false, ssr时后端isBigScreen=false,返回了相应html代码,但到了前端,在mounted()时判断是大屏,设isBigScreen=true,然后由于后端返回的html只有isBigScreen=false时的代码,结果就是Hydration mismatch了。改用v-if="$q.platform.is.desktop"来判断。
2. 一些html标签不规范的用法有可能触发“Hydration completed but contains mismatches”。 比如下面这个
<header> <h1 class="text-h6 text-bold"> {{ item.title }} <q-badge transparent align="middle" :color="getTagColor(item.tag)" :label="item.tag" > </q-badge> </h1> </header>
经过实践检验,edge ,safari,微信开发工具里都发生“ydration completed but contains mismatches”。Chrome,Firefox没有这个错。但奇怪的是本地的服务就没有报错,估计和nodejs的版本有关。去除<h1>外面的<header>就可以了。
============= 2 这个可能不是这个原因,而是谷歌广告导致的
3. 外部谷歌广告会改变html的js
线上的yunpanDetail出现了 “Hydration completed but contains mismatches.” 但本地却没问题。页面的dom被谷歌广告给破坏了。谷歌广告自动在div外面套上了一层div,改变了页面布局
<div class="google-auto-placed" style="width: 100%; height: auto; clear: both; text-align: center;"> <div class="q-item__section column q-item__section--main justify-center"> <div class="q-item__label"> <div class="text-body2 Post-body break-all"> <p> 消失的她-高清修复版 <br> <br> 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。 </p> </div> </div> </div> </div>
adsbygoogle.js?client=ca-pub-3935005489954231:51 Error: no_div at adsbygoogle.js?client=ca-pub-3935005489954231:192:483 at he.ga (adsbygoogle.js?client=ca-pub-3935005489954231:51:239) at qp (adsbygoogle.js?client=ca-pub-3935005489954231:189:747) at adsbygoogle.js?client=ca-pub-3935005489954231:189:793 at adsbygoogle.js?client=ca-pub-3935005489954231:51:434 at he.ga (adsbygoogle.js?client=ca-pub-3935005489954231:51:239) at adsbygoogle.js?client=ca-pub-3935005489954231:51:423
我觉得可能是谷歌广告的js先生成了这个tag,然后vue的vender.js后面执行时发现html和后端生成的不一样了,就发生了“Hydration completed but contains mismatches.” 还会导致页面发生“not div”的错误,广告显示不出来不说,还爱破坏了页面布局。用动态script标签在yunpanLayout的mounted hook动态添加script,确保页面dom检查过后再添加广告的div代码,经测试没有报错了。
let script = document.createElement('script'); script.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3935005489954231'; script.crossorigin = 'anonymous'; document.body.append(script);