超链接 target="_blank" 要增加 rel="noo
问题描述
在写React的时候, 由于有特殊要求需要新建窗口,于是我只能通过原始的a标签写了如下代码
<a href="https://www.baidu.com" target="_blank">百度</a>
然后控制台就报错了
Using target="_blank" without rel="noopener noreferrer" is a security risk: see https://mathiasbynens.github.io/rel-noopener react/jsx-no-target-blank
其实意思就是在没有rel=“noopener noreferrer”的情况下使用target=“_blank”是一种安全风险。
问题解决
所以我们在使用target="_blank"
的时候需要加上rel="noopener noreferrer"
<a
rel="noopener noreferrer"
href="https://www.baidu.com"
target="_blank"
>
百度
</a>
此时控制台的警告就消除了。
思考
Google官方解释为什么要这个属性呢, 加了有什么好处?
大致解释如下:
当您的页面链接至使用 target="_blank" 的另一个页面时,新页面将与您的页面在同一个进程上运行。 如果新页面正在执行开销极大的 JavaScript,您的页面性能可能会受影响。
target="_blank"也是一个安全漏洞。新的页面可以通过window.opener 访问您的窗口对象,并且它可以使用 window.opener.location = newURL将您的页面导航至不同的网址。
其实就是当你使用target="_blank"打开一个新的标签页时,新页面的window对象上有一个属性 opener ,它指向的是前一个页面的window对象,因此,后一个新打开的页面就可以控制前一个页面了,事情就是这么的可怕。而且不管它是否跨域了,都是可以的。
测试
同源情况下
我们建立一个本地服务器, 根目录下面新建一个就新建两个文件
index.html
news.html
index.html内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试首页</title>
</head>
<body>
<a href="./news.html" target="_blank">前往news页面</a>
</body>
</html>
news.html 内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试网页</title>
</head>
<body>
<h1>news页面</h1>
<script>
window.opener.alert(1);
</script>
</body>
</html>
这个时候我们在index.html点击链接后, 我们竟然可以看到,新建了一个窗口http://localhost/news.html
,但是我们可以看到在index.html
非同源情况下
我们在上面的index.html里面加入如下代码
.....
<a href="./news.html" target="_blank">前往news页面</a>
<br/>
<a href="http://localhost:3000/" target="_blank">前往React的页面</a>
.....
http://localhost:3000
是开启的一个React服务器,在React里面写一个组件
import React, {PureComponent} from 'react'
class Home extends PureComponent {
.....
componentDidMount () {
try {
window.opener.location.replace("http://www.baidu.com")
} catch (error) {
console.info("该页面没有opener!")
}
}
.....
}
当我们在http://localhost
点击前往前往React的页面
,这时浏览器为我们新建了一个窗口打开了http://localhost:3000/
,这没有什么稀奇的,但是我们可以看到,index页面竟然开了百度。