转载网址:https://juejin.cn/post/6844903879042138120
场景
公司官网上需要点击一个链接打开新标签页到第三方网站,但是总会出现第一次能打开,后面点击都是下载页面。
<a href="http://******/stock?plate=szse&stockCode=002148" target="_blank">公告</a>
复制代码
猜想:经过查阅资料后,我开始觉得浏览器认为这个网页不是html的,于是我在那个网址后面加了个查询参数&.html,确实我在本地测试时每次都能打开,不会下载,但是很不幸的是一上生产环境虽然不会下载,但是打开的页面却是空白的,找不到这个页面;失败了,只能再找原因
寻找为什么会下载?
点击链接到第三方网站时看到请求的第三方接口:
第一次响应的请求头Content-Type:text/html;
第二次以后响应的请求头Content-Type:octet-stream 浏览器解析到octet-stream会将此页面认为是下载的文件,就不会打开页面,而是下载页面寻找为什么第三方会改变响应头Content-Type?
尝试了很多,在https的网站上点击这个链接,不会出现下载的情况;而在http的网站上就会出现以上情况,不仅是a链接,连iframe也会下载。
猜想:我想是不是这个第三方网站认为http不安全,不允许链接他们网站,可那怎么解决啊,这个是人家第三方限制的,我很被动啊。
就在这时,我们主管发给我一个例子,证明我的猜想不太对,那个例子就是有一个http的官网,也是链接到同一个第三方网址,却没有下载,那个网址的a链接的写法就是多了一个属性rel="noreferrer";经过测试后,果真解决了会下载的问题,然后去看看这个属性
a标签的rel属性noreferrer的作用
当你浏览一个页面点击一个a标签链接<a href="www.baidu.com" target="_blank">
跳转到另一个页面时,
在新打开的页面(baidu)中可以通过window.opener获取到源页面的部分控制权,即使新打开的页面是跨域的也照样可以(例如 location 就不存在跨域问题), 那么你就让用户暴露在一个非常简单的钓鱼攻击之下。 第三方网站可以通过window.opener来操作源页面,会有很大的安全隐患,比如:
if (window.opener) {
window.opener.location = "**网站地址**?referrer="+document.referrer;
}
复制代码
第三方网站就可以更改源页面的地址源,你本来浏览的是自己的网站,点击了这个链接后,第三方的一个操作,你的页面就变成了第三方给你设置的钓鱼网站了。
所以为了限制 window.opener的访问行为,原始页面需要在每个使用了target="_blank"的链接中加上一个rel="noopener"属性。 rel=noreferrer表示 禁用HTTP头部的Referer属性。 然而,火狐不支持这个属性值,所以实际上你要用 rel="noopener noreferrer"来完整覆盖
why:我理解为什么我第一次点击是打开,后面就变成下载了,可能第三方网站做了安全限制,如果第三方能拿到源页面的window.opener,就认为这是不安全的,不给对方浏览,为什么呢,因为这个源页面出现了问题,责任在于这个第三方网站,它这样限制相当于提前甩锅吧(因为很有可能其他技术人员通过第三方网站窃取源页面的信息,所以这个第三方比较机智,不给这些黑客下手机会)
终于解决了