問題描述
在寫React的時(shí)候, 由于有特殊要求需要新建窗口,于是我只能通過原始的a標(biāo)簽寫了如下代碼
<a target="_blank">百度</a>
然后控制臺就報(bào)錯(cuò)了
Using target="_blank" without rel="noopener noreferrer" is a security risk: see https://mathiasbynens.github.io/rel-noopener react/jsx-no-target-blank
其實(shí)意思就是在沒有rel=“noopener noreferrer”的情況下使用target=“_blank”是一種安全風(fēng)險(xiǎn)女阀。
問題解決
所以我們在使用target="_blank"
的時(shí)候需要加上rel="noopener noreferrer"
<a
rel="noopener noreferrer"
target="_blank"
>
百度
</a>
此時(shí)控制臺的警告就消除了饿悬。
思考
為什么要這個(gè)屬性呢, 加了有什么好處?
大致解釋如下:
當(dāng)您的頁面鏈接至使用 target="_blank" 的另一個(gè)頁面時(shí),新頁面將與您的頁面在同一個(gè)進(jìn)程上運(yùn)行疹瘦。 如果新頁面正在執(zhí)行開銷極大的 JavaScript耘擂,您的頁面性能可能會受影響邑时。
target="_blank"也是一個(gè)安全漏洞努潘。新的頁面可以通過window.opener 訪問您的窗口對象懂牧,并且它可以使用 window.opener.location = newURL將您的頁面導(dǎo)航至不同的網(wǎng)址。
其實(shí)就是當(dāng)你使用target="_blank"打開一個(gè)新的標(biāo)簽頁時(shí)皱坛,新頁面的window對象上有一個(gè)屬性 opener ,它指向的是前一個(gè)頁面的window對象编曼,因此,后一個(gè)新打開的頁面就可以控制前一個(gè)頁面了剩辟,事情就是這么的可怕掐场。而且不管它是否跨域了往扔,都是可以的。
測試
同源情況下
我們建立一個(gè)本地服務(wù)器, 根目錄下面新建一個(gè)就新建兩個(gè)文件
index.html
news.html
index.html內(nèi)容如下:
<!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 內(nèi)容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>測試網(wǎng)頁</title>
</head>
<body>
<h1>news頁面</h1>
<script>
window.opener.alert(1);
</script>
</body>
</html>
這個(gè)時(shí)候我們在index.html點(diǎn)擊鏈接后, 我們竟然可以看到,新建了一個(gè)窗口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
是開啟的一個(gè)React服務(wù)器熊户,在React里面寫一個(gè)組件
import React, {PureComponent} from 'react'
class Home extends PureComponent {
.....
componentDidMount () {
try {
window.opener.location.replace("http://www.baidu.com")
} catch (error) {
console.info("該頁面沒有opener萍膛!")
}
}
.....
}
當(dāng)我們在http://localhost
點(diǎn)擊前往前往React的頁面
,這時(shí)瀏覽器為我們新建了一個(gè)窗口打開了http://localhost:3000/
,這沒有什么稀奇的嚷堡,但是我們可以看到卦羡,index頁面竟然開了百度。