rel=noopener是什么
问题的出现
昨晚上用ESLint检查代码时,出现了这样一行错误:
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"之后报错就没有了,可问题是:what’s this?
关于rel
rel是relationship的缩写,用于指定当前文档与href链接的文档的关系(顺便一说,rev属性已在HTML5中废弃)。MDN中如此描述:
rel
对于锚点来说,rel具有href的属性, 该属性指定了目标对象到链接对象的关系。该值是空格分隔的列表关系值。 该值和语义可能将会被一些权威文档编者赋予不同的含义。 在默认的情况下,如果没有其它定义,是无效的,只有在 href 存在的情况下,使用该属性。
并且在target 属性后面写到:
注意:使用target时,考虑添加 rel=”noopener norefferrer” 以防止针对 window.opener API 的恶意行为。
由此看来,写上这条属性的好处首先是让链接的语义更加明确,语义明确后,自然是搜索引擎友好,然后还可以提升网页的安全性。
问题究竟是什么
关于window.opener,MDN里有这么一句:
备注
如果当前窗口是由另一个窗口打开的, window.opener保留了那个窗口的引用. 如果当前窗口不是由其他窗口打开的, 则该属性返回 null.
我想问题大概就是在这里吧,链接到信任的站点自然可以灵活地使用,可是一旦链接到钓鱼网站,这个网站可以做什么你总是难以预料。但总的来说,这种行为的潜在风险是远远大于好处的。
接下来该怎么做
对于rel="noopener"这个属性,在Chrome 49+、Opera 36+中可以将window.opener设置为null,但如果浏览器是比较老的版本,实际上要使用rel="noopener norefferrer"去完整覆盖,将HTTP头部Referer属性也禁用掉。
其实我个人还是偏向于听从最开始那篇文章里的建议:
Don’t use target=_blank (or any other target that opens a new navigation context), especially for links in user-generated content, unless you have a good reason to.
所以说,尤其是网站用来对外提供给用户使用的情况下,请不要低估这个问题,更没有理由去忽视这个问题。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!