前段时间写 React 代码的时候,eslint 总是会在报一个下面的错。
这种 a 链接的代码在 Html 里面写了这么多年都一直没有问题的,怎么在 React 里面总是不符合要求,于是我扒了一下前因后果。
https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md
看 Eslint 这个规范文档里面说了,当使用 target="_blank" 属性来标记一个打开新标签页的 a 链接时,如果不带 rel="noreferrer noopener" 会是一个严重的安全漏洞。
在 https://mathiasbynens.github.io/rel-noopener/ 这个页面里,当你点击第一个链接(Click me!!1 same-origin),会打开一个新的页面,新的页面没有任何异常,但是当你重新回到当前这个页面时,你会发现这个页面的顶部变了!
这是由于这个链接没有带 noopener 属性,从而当打开一个新的页面时,这个新的页面拥有了当前这个页面的 document 对象完整控制权。
看一下新打开页面的源代码:
<script>
if (window.opener) {
opener.location = 'https://mathiasbynens.github.io/rel-noopener/#hax';
// Just `opener.location.hash = '#hax'` only works on the same origin.
} else {
document.querySelector('h1').innerHTML = 'The previous tab is safe and intact. <code>window.opener</code> was <code>null</code>; mischief <em>not</em> managed!';
}
</script>
很简单的一段代码,但是却可以做很多事情。
举个例子:
假设在淘宝网上有一个 B网站链接没有带 noopener,当你打开了 B 网站的时候,B 检测到你没有添加 window.opener 的时候,我就把你网站重定向到一个高仿的淘宝网站。
当你从 B 网站回到前面的淘宝网站时,你可能并不会注意这个时候已经是一个假淘宝网了。然后让你输入用户名密码进行登录等等操作。这个时候你的淘宝账号就泄露了。
其实这个就是网络钓鱼的过程。
所以,当你的网站里面有外链的时候,都应该在连接上加上 noopener 这个属性。当我们在开发网站的时候,务必要给每个新也页面打开的链接都加上 noopener 属性。
关于 noopener 的常见问题(FAQ):
noopener 是否会对网站 SEO 有影响?
没有影响,openner 属性是一个解决安全问题的属性,没有任何 SEO 方面的影响。
noopener 是否会对 Affiliate 链接有影响?
没有影响,这篇文章说的比较详细。
noopener 是否一定要添加?
当你的网站没有外链或者链接出去的网站是你信任的网站时,可以不添加。其他 target="_blank" 的情况建议都添加。而且,wordpress 现在也是默认添加的。