应怎样看待 target="_blank" 的使用?
应怎样看待 target="_blank" 的使用?
26 个回答
我觉得target="_blank" 的使用是一门很深的学问,千万不要对于所有的元素都一概而论,打个比方:比如google在处理分页的时候使用target="_blank",想象一下会是什么样的后果;而在处理搜索结果列表的时候使用target="_blank"却又是一件很惬意的事。所以得针对不同的对象谨慎使用target="_blank"。
整理了一下个人觉target="_blank"的使用需要注意的地方:
1,正文的注解一般都target="_blank";(让用户为了注解而离开正文是件比较傻的事,一般新闻网站都会强行使正文中的链接都target="_blank"。)
2,站外链接尽量使用target="_blank";(这个不用解释了吧)
3,表单页面的中的target="_blank"最应该谨慎使用;
4,针对同样元素要一视同仁,别上一个列表用target="_blank"下一个列表就不用,同样对于导航这样的重要的元素要特别重视。
原则差不多就是:内容与当前内容关联性不大可使用target="_blank",离开本页会对用户产生损失一定要使用target="_blank",特别是返回上一页已经不能还原当时内容的情况,所以视频网站在这方面下足了功夫,可以多学习下此类网站关于target="_blank"的用法。
另外我不认为使用或者不使用target="_blank"是绑架用户,什么都不思考什么都不做才是对不起用户,个人意见。其实国外的网页操作“心智模型”是没有打开个新的页面的,Jackon Nielsen有篇文章
《Avoid Within-Page Links》,里面讲到用户对链接的心智模型应该是这样的:
1、点击一个链接应该跳转到一个新的页面;
2、点击了一个链接,老的页面不应该还在;
3、新页面替代了老页面;
4、你一眼看到的应该是新页面;
5、有个后退按钮可以让你退回老页面;
所以,如果你去Amazon看,上面所有商品点击都是直接跳转,这跟淘宝截然不同。
比较有趣的是,google英文和中文站不一样,点击一个搜索结果,中国站会弹出新窗口,而英文站,一律都是当前页刷新,即交互反馈不一样。
所以,我认为用不用target=_blank,在大的层面,考虑使用人群差异和文化环境;
其次,考虑产品当前链接的使用情况,例如不破坏当前操作流的,就不应该使用。而例如帮助信息,与当前用户使用不产生影响的,可以使用。
http://www.budoued.com/?p=218
站外链接要用。
很长的链接列表可能要用(比如搜索引擎的结果,知乎的feed)。
目标页与当前页UI或者内容相差很大的链接可以用(例如从门户网站的首页进入其中的某个频道)。
- 何时使用 target="_blank"
- 被低估的 target="_blank" 漏洞
- 相关资源
何时使用 target="_blank"
锚链接可以选用 target 属性 控制点击链接时的行为,_blank 是该属性可用值之一,点击链接时它会告知浏览器打开一个新的窗口(或者标签页,根据用户偏好设置)。
<form> 也可以有 target="_blank"。我认为这是一个罕见的用法,但本文叙述的思维方式也将适用。
target="_blank" 曾经在 HTML 中是“无效”的,但因为可以被正常执行,人们还是会使用它。现在,它在 HTML5 中完全有效,但有合理的理由使用它吗?
无理的理由:因为你喜欢用
不论喜欢与否,target="_blank" 是对链接在同一页面里打开(如同链接拥有 target="_self")这种默认行为的改变。
也许你已经开发了一种 所有链接都在新窗口/标签页中打开 的个人品味,对你而言这是美妙的,但安全的假设是 对大多数用户而言 默认行为最为舒适,并且因此 你强制不同的行为表现会导致不适。
如果它只是你个人的内部工具,你想怎样做都行。如果其他人也使用该网站,保留普适性。
同样值得注意的是,用户可以使用 [快捷键]-点击 强制在新窗口/标签页中打开链接。这对他们意味着打开链接的两种行为都可用。也意味着如果你喜欢打开新标签页,可以这么做 并也可以避免把这种行为灌输给其他人。
使用 target="_blank" 时,仅有这种行为可用。
无理的理由:仅仅因为你希望用户永远不离开你的页面
品牌 品牌 塑造品牌!吸引眼球。绩效指标。客户互动。
其他网站也许都运用标准类型的链接,但我们的网站特别。我们的网站更有地位并且应当永远不被遗忘。
无理的理由:“内部”链接与“外部”链接不同
我们会让“内部”链接(指向自己网站的链接)表现正常,但“外部”链接(指向其他网站的链接)打开新的窗口/标签页。
这与上述的两个原因相关,甚至比它们更糟。你已经明白 理想的链接类型是标准型,但如果这意味着用户会离开你的网站,你就愿意打破这一理想。
我听到许多人说这是“约定俗成”理之当然,并不是。
无理的理由:链接指向 PDF 文件
或者是网页文档之外的其他任何资源,它们凭什么可以特殊化?你依然可以使用后退按钮从文件返回。如果你是想帮助用户在不打开该文件的情况下下载它,虽然这是一个有价值的用户体验目标,但可用其他途径来实现。首先,使用 download 属性。
无理的理由:我的客户想要这种方式
因为我们的精力有限,我妥协接受了客户的“我不想因此起争执”。但这样处理事情很奇怪,无论如何这里必须争取。如果客户在这里就不信任你,那他们还信任你什么呢?
或许我可以这样处理:链接的默认行为是正常打开,但因为某些原因我们可能想要打破并转变这种行为,但对大多数链接我们不这么做,我们不想把自己的需求强加给用户并因为这样一件小事潜在地挫败他们,我们希望用户对我们感觉良好。
那就希望你冷静又有依据的处理能够帮助你的客户对你感觉良好。
无理的理由:无限滚动页面上的链接
处理无限滚动是棘手的,某些情况下不间断的提供内容具有良好的用户体验,但如果处理不当也会适得其反导致糟糕的用户体验。多数情况下,“返回”无限滚动页面时应当回到先前的浏览位置,你的工作是处理这棘手的问题,而仅仅通过强制在新窗口中打开链接来避免这个问题 则是在回避你的工作。
合理的理由:用户正在播放流媒体内容
例如:音乐、视频、播客……
转变页面将会打断用户正在播放的媒体内容。对于这种情况,要么在新标签页中打开链接,要么询问他们是否确定离开当前页面。你要在不影响用户播放进程的情况下,尝试做出正确的交互设定。
理想的做法是:如果媒体处于播放状态,以一种特殊的方式处理链接;当媒体不在播放状态,链接保持正常行为。最好能记录媒体的播放进度,以便从上次停止处恢复播放。例如打开页面自动加载播放进度,或者在时间轴下方添加一个箭头标记“你上次播放到这里了”。
话虽如此,相当数量的流媒体视频网站 并没有提供关于播放进度的设定,因为切换视频时的摩擦过渡对他们来说非常重要(视频广告),这无可厚非。但如果他们能在这里提供一点帮助会更好,上文提及的「箭头标记」就适用。
合理的理由:用户正在页面上进行某些操作,如果当前页面改变可能导致操作丢失。
也许用户正在网站上写作,安排事项或做其他任何工作,点击一个链接导致页面改变会是一个惊心,糟糕的瞬间。我刚刚正在做的事情全都付诸东流了?
即使你去做一些事情以确保用户的操作不会丢失,还是要避免让人陷入这种惊慌为好。
这种情况常见于用户在网站上书写文章或编写代码,几个可行的处理方法:- 仅当与编辑器有交互时,指向另一个页面的 有明确的“了解更多”样式的链接(例如 [?] )在新标签页中打开。
- 标准的链接(例如页脚的链接)有正常的行为,但如果检测到用户在编辑器中有未保存的更改,则在用户离开页面之前提示保存它们。
- 如果用户直接访问另一个网站(或者浏览器崩溃),在 localStorage 中保存编辑状态,这样操作就不会丢失。
付款是另一个例子,你当然不想在付款过程失去顾客。应当在不影响付款进度的情况下打开指向例如“收货地址”这样的链接。
“阅读一篇文章”,在我看来不符合这里的条件。因为它(通常)很容易返回(大多数浏览器甚至向下滚动到先前的浏览位置),这里没有真正的丢失风险,并且读者实际上是泛泛读者。
_________________________________________________________________________________________
被低估的 target="_blank" 漏洞
人们使用 target="_blank" 时,通常不知道这样一个事实:
我们链接到的页面,可以通过 window.opener 对象获取来源页面的部分使用权限。特别要注意,window.opener.location 能够跨来源(跨域)!(尽管像 window.opener.document 这类对象都受到 CORS 限制。)
新打开的标签页可以通过修改 window.opener.location,将来源页面重定向到一个钓鱼页面,界面样式模仿来源页面并索要登录凭证。用户很可能不会留意到这个动作,因为他们的注意力在新标签页上,而重定向发生在幕后。在重定向到钓鱼页面之前,通过添加一个延迟,这种幕后的攻击可以做得更加隐蔽。(参考 Tabnabbing)
攻击举例:创建一个“病毒”页面,伪装成可爱的宠物图片,玩笑等诸如此类。分享到 Facebook(已知的通过 _blank 打开链接的社交媒体)每当有人点击链接打开新标签页-执行
window.opener.location = 'https://fakewebsite/facebook.com/PHISHING-PAGE.html';
……来源页面重定向到一个要求用户重新输入 Facebook 密码的钓鱼页面。
如何预防
为了防止页面滥用 window.opener,使用 rel="noopener"。这样可以确保在 Chrome 49 和 Opera 36 及后续版本中 window.opener 的值为 null。
对于老版本(和尚不支持 rel="noopener" 的)浏览器,你可以使用 rel="noreferrer",这同时也会禁用 HTTP 头字段的 Referer 字段;或使用以下 JavaScrpt 变通方案,有可能触发弹出式窗口拦截器:
var otherWindow = window.open();
otherWindow.opener = null;
otherWindow.location = url;
注意,基于 JavaScript 的变通方案在 Safari 中无效[Safari 的跨来源(跨域)安全规范会阻止修改位于不同来源(域)的子窗口的 window.opener,但却仍然允许子窗口访问 window.opener.location]。对于 Safari 的支持,打开新标签页时注入一个隐藏的 iframe,紧接着立即移除这个 iframe。
除非你有一个合理的理由,否则不要使用 target="_blank"(或其他任何会打开新导航关系的 target),尤其是 UGC(User-generated content)里的链接。
漏洞实例
- Facebook 仍未预防此漏洞。
- Twitter 没有在 Safari 上预防此漏洞。他们既没有使用 rel="noopener"(Safari 目前还不支持)也没有使用 rel="noreferrer";而他们正在使用的变通脚本在 Safari 中不能正常工作。
- Instagram 仍未预防此漏洞。8月28日更新已预防此漏洞。
The Practical Dev 的网站上运行了一个利用这一漏洞的脚本,目的是为了警醒用户,如果他们来自使用了 target="_blank" 并未对这一漏洞采取预防措施网站。
if (window.opener) {
window.opener.location = "Phishing"+document.referrer;
}
他们的社交媒体主页上有自己网站的链接,如果你点击链接,然后查看原来的标签页,就会明白是怎么一回事。
具体演示:- 访问 The Practical Dev 的 Facebook 主页。
- 点击主页信息中的 https://dev.to/ 链接,将会打开一个新标签页。
- 观察原来的标签页,已经重定向到这个页面。
这个漏洞并非众所周知,且完全被低估。它已经在 WHATWG(网页超文本应用技术工作小组)的一个邮件列表中被提出。
发现有知名网站仍未预防这一漏洞,可在评论中留言。
_________________________________________________________________________________________
相关资源
-
When to use target="_blank"
| CSS-Tricks
-
About rel=noopener
| Mathias Bynens
-
[whatwg]
Clarification for window.opener.location.href | Nicholas C. Zakas on 2015-01-05
-
Phishing
by navigating browser tabs | Bughunter University
-
Tabnabbing:
A New Type of Phishing Attack | Aza Raskin
-
The
target="_blank" vulnerability by example | The Practical Dev
-
blankshield
| Prevent reverse tabnabbing phishing attacks caused by _blank (预防脚本)
- Target="_blank" - the most underestimated vulnerability ever | Jitbit
因为大部分小白用户不知道鼠标中键单击可以在新页面打开,所以还是帮他们加 _blank 吧。
呵呵
这就跟大部分小白用户不知道 Home 键可以返回顶部一样,我们前端不得不帮他们加一个「返回顶部」按钮。
呵呵
我目前故意安装了 Death to _blank 插件,来防止新开页面。我就是不喜欢开那么多页面。
知乎和微博也有这个弊端,例如我在首页看到一个问题,可是是直接跳转,等我再回到首页还要从最上面向下看。微博主要是原文评论和原文转发不能_blank,真的很烦人,每次都要用右键新开页签。
所以在选择用不用target=_blank的时候一定要对当前页面的使用频率,和当前页面定位位置进行评估
我实在实在实在不喜欢按鼠标中键,没人跟我一样吗?
知乎是加了这个的。如果不加,你觉得等你看完一个问题再点返回,还找得到刚才看到哪儿了吗。。
最气的是有时候首页刷新了,那就GG
另外在我的网上冲浪历程里,新页面打开的最佳实现,是在著名电影网站 javbus ,他们的页面本身是不加的,于是我喜欢右键加T。因为如果快速连按鼠标中间,确实是体验不佳。
- 外链
- 由总到分(如搜索列表中,对某一项结果的点击)
- 在操作流程中,与流程本身无关的操作
- 表单提交(如注册,意见反馈)
何时使用:
当前的页面包含动态更新的内容,如各种微博产品
网页内容包含重要的在编辑表单/文档,且尚未实时保存
- 跳转到站外,或者其它频道。
- 和本页内容主题没有关联性的连接。
- 只是一个属性,虽然说Document Type Strict不可以使用这个属性,可是HTML5删除了很多属性和已然保留着Target,说明还是有他的意义的,需要的时候就使用就是了
结合window.opener存在漏洞,请自测:
假设有页面a.html和b.html,在b页面中加入以下内容,a中通过target="_blank"打开b页面
if (window.opener) {
opener.location = "https://www.jottown.com"
alert("存在漏洞!看看a页面")
} else {
alert("不存在漏洞!")
}
懒人版:
a.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<a href="./b.html" target="_blank">aa</a>
</body>
</html>
b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
if (window.opener) {
opener.location = "https://www.jottown.com"
alert("存在漏洞!看看a页面")
} else {
alert("不存在漏洞!")
}
</script>
</body>
</html>
大半夜不睡的,就为了讨个赞,有啥问题可以去https://jottown.com找我
抛开那些门户网站和商业站不谈(他们开不开新窗口基本都是基于别有用心的)。一个正常不反人类的(单一)站点,各层次目录&分类浏览是不该开新窗口,但最终内容展示页面则必须开新窗口。
就这么简单的规则
这就是一个坑,国内互联网刚起来的时候各种网站就是靠流量赚钱,在新窗口打开是获取流量最简单的方式,然后就培养了一批又一批在新窗口打开的用户。
w3c标准里的内容(history),浏览器厂商不断完善,却被这样的小习惯完爆。