foreword
The security optimization of webpages is an issue that is increasingly valued by developers (such as configuring SSL
certificates to achieve website https
access, preventing XSS
attacks etc.), today we will analyze 掘金
how to implement "blocking" when the website jumps to external links ” and notify the function.
1. Business scenarios
When opening a link in 掘金
an article or boiling point, if it is 外部链接
(a link not on this site), it will first jump to a risk warning page, informing the user of the new page that is about to be opened. We are not responsible for any problems that occur not on this site Provide, pay attention to the security of account property. It's actually a disclaimer. (The following will use an external link in an article as a demonstration. Because the loading animation of this website is very good )
The most important prompt page is as follows:
2. Code Analysis
1. Link elements
We need to analyze its code (visible), and first focus on the elements that click to jump. Open the console 检查元素
to see what's special about this link element.
From the picture above, we can intuitively see that the Nuggets internal link is spliced before the link https://link.juejin.cn/?target=
, and the URL =
after that is the real URL.
2. Risk warning
Then let's look at the risk warning page.
On 风险提示
the page , just take out the parameterURL
on and display it on the page. target
(URL parameter transfer is common in various search pages)
3. Link handling
Of course, the key link is when this link was processed like this. Let's first see if it is processed when editing the article.
As can be seen from the figure above, links are not processed in real time when editing articles. We know that Nuggets' draft articles are saved in real time, so let's see if the data sent in the request has been processed.
It can be seen from the sent request that the link mark_content
in has not been processed, so the link should be processed in the background.
3. Encoding
1. Risk warning page
Nuggets' technology stack is Vue2.x
, here is the way to write Vue2.x
the version :
// 风险提示页
<template>
<div class="box">
<div class="tip-box">
<img
class="logo"
src="https://lf-cdn-tos.bytescm.com/obj/static/link_juejin_cn/assets/logo_new.0ec938fb.svg"
/>
<div class="content">
<div class="title">
<del>冰冰你个小可爱</del> 即将离开稀土掘金,请注意账号财产安全
</div>
<div class="link">{
{ target }}</div>
<button class="btn" @click="navigateToTarget">继续访问</button>
</div>
</div>
</div>
</template>
<script>
export default {
name: "RiskTip",
data() {
return { target: "" };
},
methods: {
// 获取 url
getTargetURL() {
const query = window.location.href.split("?")[1] || "";
const target = query.split("target=")[1] || "";
this.target = window.decodeURIComponent(target);
},
// 跳转页面
navigateToTarget() {
if (!this.target) {
return;
}
window.location.href = this.target;
},
},
mounted() {
this.getTargetURL(); // 获取 url
},
};
</script>
<style scoped>
.box {
height: 100vh;
background-color: #f4f5f5;
}
.box .tip-box {
position: absolute;
left: 50%;
top: 30%;
max-width: 624px;
width: 86%;
background-color: #fff;
transform: translateX(-50%);
padding: 30px 40px 0;
box-sizing: border-box;
border: 1px solid #e5e6eb;
border-radius: 2px;
}
.box .tip-box .logo {
display: block;
width: 116px;
height: 24px;
position: absolute;
top: -40px;
left: 0;
}
.box .tip-box .content .title {
font-size: 18px;
line-height: 24px;
}
.box .tip-box .content .link {
padding: 16px 0 24px;
border-bottom: 1px solid #e5e6eb;
position: relative;
color: gray;
font-size: 14px;
}
.box .tip-box .content .btn {
display: block;
margin: 20px 0 24px auto;
color: #fff;
border-radius: 3px;
border: none;
background: #007fff;
height: 32px;
font-size: 14px;
padding: 0 14px;
cursor: pointer;
outline: 0;
}
</style>
Let's see how Kangkang works:
2. Front-end link processing
It can be seen from the request parameters that the links in the rich text are not processed, so if we need the front end to process and then return to the background, we need to use regular expressions to replace all the links in the rich text. Here we encapsulate a public method:
// utils/index.js
/**
* 替换富文本中的链接
* 将富文本中的不是本站的链接前追加 "https://link.juejin.cn/?target="
* @param html 传入富文本
* @returns html 处理后的富文本
*/
export const replaceHTMLHref = (html) => {
const juejinReg = /https:\/\/juejin.cn/g; // 匹配"https://juejin.cn"
const juejinSignReg = /JUEJIN_URL/g; // 匹配"JUEJIN_URL"
const urlReg =
/((http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*(?!juejin.cn)[\w\-\@?^=%&/~\+#])?)/g; // 匹配所有网址
/**
* 匹配替换三次
* 第一次将所有"https://juejin.cn"替换为"JUEJIN_URL"
* 第二次将所有网址增加前缀"https://link.juejin.cn/?target="
* 第三次将所有"JUEJIN_URL"替换为"https://juejin.cn"
*/
const result = html
.replace(juejinReg, "JUEJIN_URL")
.replace(urlReg, "https://link.juejin.cn/?target=$1")
.replace(juejinSignReg, "https://juejin.cn");
return result;
};
Let's write a piece of code to test whether Kangkang takes effect:
// 省略其他非关键代码
import {
replaceHTMLHref } from "@/utils";
const str = '一个外部网址:\nhttps://webgradients.com/\n又一个外部网址:\nhttps://www.baidu.com/\n掘金:\nhttps://juejin.cn/';
console.log(replaceHTMLHref(str));
So far, the function of front-end processing links in rich text has been realized.
4. Nuggets eggs
When viewing the request to edit an article, I accidentally discovered that the console of the edit article page will print the following content:
Many websites have console easter eggs, but I have to say that the official Nuggets are really cute. ٩('ω')و
summary
By checking elements, viewing requests, etc., the possible implementation of Nuggets' "jump external link risk reminder" is deduced. But I believe that what we have learned from this case is not only a solution, but also a way of thinking about dealing with the problem. Only by constantly learning from excellent projects can we better improve our technical level.