一个大型的正规网站,增加一个 外链中转页 是有必要的。合理的交互设计,不仅能有效保障用户体验,又能帮助网站收集外链数据,优化运营管理。
目录
1、为什么使用跳转页面来管理外链
1.1、安全性
1.2、搜索引擎优化
1.3、外链数据统计
1.4、外链网站引流
1.5、业务功能扩展
2、CSDN外链跳转页设计
3、外链跳转演示
3.1、跳转到外链-无参数
3.2、跳转到外链-有参数
3.3、跳转到本地/本网域页面
3.4、空地址
3.5、跳转到本页面/页面标签
3.6、跳转到无效地址
4、外链跳转逻辑实现
运行环境:
- Windows-10-BusinessEditions-21h2-x64
- Google Chrome-112.0.5615.50-x64
- HTML5
1、为什么使用跳转页面来管理外链
1.1、安全性
- 网站安全评级
对外链进行识别、过滤,提醒用户即将跳转到外部网站。
对外链网站进行安全评级,并进行黑白名单控制,把它认为不安全的网站直接拦截。
- 用户隐私保护
直接跳转,外链网站可以轻松拿到用户正在浏览页面的URL 和 UserAgent,有可能会造成用户信息泄露等安全和隐私问题。而通过跳转页中转,对HTTP请求头做特殊处理(如:去掉 Referer 请求头),被访问网站只能知道链接是来自本站。
- JS安全漏洞
可以有效的防止外链接网站通过访问 window.opener 修改原网站location的安全漏洞。
- 域名SSL认证
对于非HTTPS的外链域名,进行提示。
通过SSL认证的中转域名来控制外链,整站的链接都是https。
1.2、搜索引擎优化
如果外链的网站被搜索引擎降权,那么本网域名也会有被降权的风险,而使用 中转域名 跳转可以避免 主域名 产生这样的风险(注:可通过在a标签加上关系属性值 rel="nofollow" 来解决)。
1.3、外链数据统计
用于链接分析,可以统计有多少用户点了外链?外链网站类型?
1.4、外链网站引流
一般情况下,高权重的网站会严控给低权限的小网站引流。小网站要想通过大网站引流,是需要花钱买流量的。
1.5、业务功能扩展
在中转页面对外链接进行功能上的特殊处理,如:
- 在中转页面放广告、推热点事件;
- 对外链url添加参数(如:utm_source)进行不同的处理;
2、CSDN外链跳转页设计
以下为CSDN跳转外链页,包括:本站Logo、警示语、外链URL、操作。
3、外链跳转演示
以下针对 a标签赋值的不同,进行举例演示。
3.1、跳转到外链-无参数
如:CSDN首页-无参数
3.2、跳转到外链-有参数
如:CSDN搜索-有参数
3.3、跳转到本地/本网域页面
- 本例中的本地网页,如:file:///E:/Workplace/h5/LocalPage.html
- 同域名二级子域名,如:https://blog.csdn.net/
3.4、空地址
空地址,默认打开当前页面,a标签 赋值为 空串,如:""
3.5、跳转到本页面/页面标签
打开当前页面,a标签 赋值为 #
3.6、跳转到无效地址
a标签 赋值为 一个无效的URL,如:ABC
4、外链跳转逻辑实现
以下代码通过给 a标签 指定 class,实现外链中转控制,如果生产环境使用代理服务器(如:nginx),请根据实际需求调整JS代码。
请将以下HTML保存为到本地(如:E:/Workplace/h5/rewriteUrl.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>外链跳转检测提示</title>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
// 获取URL中的域名
function getUrlDomain(objUrl) {
// 非标准域名
if (objUrl == "" || objUrl == "#" || objUrl.indexOf("//") == -1) {
return "";
}
var urls = objUrl.split("//");
var urlDomain = urls[1];
var delimiterPosition = urlDomain.indexOf("/");
if (delimiterPosition > 0) {
urlDomain = urlDomain.substring(0, delimiterPosition);
}
var paramPosition = urlDomain.indexOf("?");
if (paramPosition > 0) {
urlDomain = urlDomain.substring(0, paramPosition);
}
// 此处根据需要添加逻辑,获取一级域名(对于相同一级域名的直接跳转,不弹出提示)
return urlDomain;
}
// 站外链接跳转提示
$("a.ext-link").click(function () {
let gotoUrl = $(this).attr('href');
if (gotoUrl == "" || gotoUrl == "#") {
// 页面内跳转(如:页面标签)
return true;
} else if (gotoUrl.indexOf("//") == -1) {
alert("非法链接");
return false;
}
let gotoDomain = getUrlDomain(gotoUrl);
let siteDomain = document.domain;
console.log("gotoUrl: " + gotoUrl);
console.log("gotoDomain: " + gotoDomain);
console.log("siteDomain: " + siteDomain);
// 非本站跳转则弹出提示
if (gotoDomain != "" && siteDomain != gotoDomain) {
// 此处也可以提交给后台的API处理
return confirm(`您即将离开本站,去往【${gotoUrl}】`);
}
});
});
</script>
</head>
<body>
<ul>
<li><a href="https://www.csdn.net/" class="ext-link" target="_blank">CSDN首页-无参数</a></li>
<li><a href="https://so.csdn.net/so/search?q=狂龙骄子&t=blog" class="ext-link" target="_blank">CSDN搜索-有参数</a></li>
<li><a href="file:///E:/Workplace/h5/LocalPage.html" class="ext-link" target="_blank">本地文件</a></li>
<li><a href="" class="ext-link" target="_blank">空地址</a></li>
<li><a href="#" class="ext-link" target="_blank">本页地址</a></li>
<li><a href="ABC" class="ext-link" target="_blank">非法URL</a></li>
</ul>
</body>
</html>
附录:
- 常见前端漏洞及防御方法之 a标签钓鱼攻击
- 什么是UTM参数