[TOC]

0x00 简单示例

1.JS referrer 来源页判断跳转返回

简单示例:

1
2
3
4
5
6
7
if(document.referrer.indexOf("weiyigeek") != -1){
window.location.href="https://www.weiyigeek.top/";
} else if(document.referrer.indexOf("blog") != -1){
window.location.href="https://blog.weiyigeek.top/";
} else {
window.history.back();
}


2.JS location URL字符串截取与过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<script>
// 获取请求的变量
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}

// 过滤特殊字符
function filterStr(str)
{
var pattern = new RegExp("[`~!@#$^*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?%+_]");
var specialStr = "";
for(var i=0;i<str.length;i++)
{
specialStr += str.substr(i, 1).replace(pattern, '');
}
return specialStr;
}

// 获取指定key并进行输出
var key = getQueryVariable("key");
if (key) {
// decodeURI(key) 解决URL里中文编码问题
document.getElementById("key").innerText=filterStr(decodeURI(key));
}
</script>

0x01 进阶示例

1.JS 异步编程实例

描述: 下列的所有概念也适用于其他异步编程的语言.

JavaScript 两种种异步方式(单线程编程语言):

  • 传统回调函数方式: (Callback Function) 例如 setTimeOut , 缺点是容易导致函数回调地狱问题,即一个函数执行完在执行内部另外一个一层一层嵌套。
  • Promise 异步方式:(Promise 承诺) 寓意这个去这个请求会在未来某一个时刻返回,它很好的解决了回调地狱的问题,优点是可以用链式结构将多个异步操作串联
  • async / await 异步方式:是ECMA17新标准语法糖,让异步操作变简单的,这两关键字基本同根同生,被 async 修饰的 funcation 接受 请求必须用 await

Tips : JavaScript 是单线程的机制,其优点是由于所有操作运行在一个线程中,无需考虑线程同步和资源竞争的开销,避免了线程之间的频繁切换和竞争问题,降低了开销


简单示例:
例如:传统的回调函数导致的回调地狱问题。

1
2
3
4
5
6
7
8
9
setTimeout(() => {
console.log("第一次等三秒");
setTimeout(() => {
console.log("第一次等三秒")
setTimeout(() => {
console.log("第一次等三秒")
},3000);
},3000);
},3000);


例如:fetch 向服务器请求,返回Promise对象,渲染前端,如果可以使用then 进行接受 返回的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 示例1.注意使用时需要设置被请求CORS policy将'Access-Control-Allow-Origin' header设置为*。
fetch("https://blog.weiyigeek.top/atom.json",{
headers:{
'Authorization': localStorage.getItem('token')
}
}).then((response)=>{console.log(response.json())})


// 示例2.可以不断追加类似java8 stream,这样的链式调用避免了层层嵌套,一个人东西的出现一定是解决某类问题。
fetch("https://blog.weiyigeek.top/atom.xml").then((response )=>{
console.log(response);
return response.json(); // 先将结果转换为 JSON 对象
}).then((data)=>{
console.log("用链式结构将多个异步操作串联");
this.setState({ // 使用JSON对象
name: data.info.name,
phone: data.info.phone
});
}).then((res)=>{
console.log("用链式结构将多个异步操作串联");
})

// 示例3.异步中的异常操作我们采用是类似于JAVA的语法catch、Finally进行请求过程中的异常捕获。
// catch 触发后then代码块中的代码将不会执行
// finally 最终完成执行的代码块,其使用来释放资源/关闭声明请求/清理工作
fetch("https://blog.weiyigeek.top/atom.xml").then((response)=>{
console.log(response.json());
}).then((res)=>{
console.log("用链式结构将多个异步操作串联");
}).catch(error=>{
console.error("如果程序报错输出错误信息 :"+error);
}).finally(()=>{
console.info("最终完成执行的代码段-> 跳转到UP主首页");
setTimeout(function(){
window.location.href="https://space.bilibili.com/385802642/article";
},5000)
})

WeiyiGeek.fetch示例演示

WeiyiGeek.fetch示例演示


例如,Async 与 await 使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// 示例1.await只在异步函数中有效。
async function F(){
const respnse = await fetc('https://blog.weiyigeek.top/');
const json = await response.json
}

// 示例2.如果有多个Promise一定使用Promise.all 然后再使用await效率会提升一倍,否则会打破原本线程并行。
async function f(){
const promiseA = await fetc('https://blog.weiyigeek.top/');
const promiseB = await fetc('https://space.bilibili.com/385802642/article');
const [a,b]= await Promise.all([promiseA,promiseB]);
}

// 示例3.Async 与 Await 闭坑指南
// 方式1,
async funcation f(){
await someAsyncOperation();
}
// 方式2,更简洁的写法匿名函数写法
(async () => {
await someAsyncOperation();
})();

// 此种方式会直接运行console.log
async funcation f(){
[1,2,3].forEach(async (i) => {
await someAsyncOperation();
});
console.log("done") // 直接运行此处
}
}

// 如果我们希望等待循环中的异步操作都一一完成之后才继续执行,我们就需要使用传统的for循环。
async funcation f(){
for (let i of [1,2,3]) {
wait someAsyncOperator();
}
console.log("done");
}
f();

// 如果想使用循环中的所有操作都并发执行可以使用 for await语句也可以达到上述效果,所以说就跟你对象一样,必须相互配合才能完成一些事情。
async funcation f(){
const promises =[
someAsyncOperator();
someAsyncOperator();
someAsyncOperator();
];
for await (let result of promises){
result
}
console.log("done");
}


2.JS copy事件监听处理在复制页面文字时自动在末尾加上版权说明

描述: 我们可以在网站页面上绑定一个copy事件,当你复制文章内容时将会自动在剪切的文字后加上一段指定版权声明。

相关技术以及事件监听器(EventListener)介绍说明:

1
2
3
4
5
6
7
8
9
10
# element.addEventListener(type, handle, false);
type: 事件触发类型,如click,keypress等等,下面我们详细的讲讲事件类型
handle:事件处理函数,事件出发后,定义可能发生的变化!
false: 表示事件冒泡模型,一般来说都是false

# event.clipboardData
该属性保存了一个 DataTransfer 对象(用户剪切板的内容),该对象可用于format数据的类型有`text/plain, text/uri-list`

# event.preventDefault()
该方法阻止元素发生默认的行为,例如当点击提交按钮时阻止对表单的提交阻止以下 URL 的链接。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
// 监听整个网页的copy(复制)事件
document.addEventListener('copy', function (event) {
// clipboardData 对象是为通过编辑菜单、快捷菜单和快捷键执行的编辑操作所保留的,也就是你复制或者剪切内容
let clipboardData = event.clipboardData || window.clipboardData;
// 如果未复制或者未剪切,则return出去
if (!clipboardData) { return; }
// Selection 对象,表示用户选择的文本范围或光标的当前位置。
// 声明一个变量接收 -- 用户输入的剪切或者复制的文本转化为字符串
let text = window.getSelection().toString();
if (text) {
// 如果文本存在,首先取消文本的默认事件
event.preventDefault();
// 通过调用常clipboardData对象的 setData(format, data) 方法;来设置相关文本
// setData(format, data);参数
// format 一个DOMString 表示要添加到 drag object的拖动数据的类型。
// data 一个 DOMString表示要添加到 drag object的数据。
appendMsg=document.getElementsByClassName("copy-copyright")[0].textContent;
appendMsg="\n原文作者: WeiyiGeek [https://weiyigeek.top]"+'\n'+appendMsg+'\n'+"更多最新文章, 请关注我的微信公众账号【WeiyiGeek】或者【B站专栏】哟, 谢谢支持!(๑′ᴗ‵๑) ❤\n";
clipboardData.setData('text/plain', text + '\n'+ appendMsg);
}
});
</script>

复制事件触发结果:

1
2
3
4
5
Let Encrypt快速颁发及自动续签泛域名证书实践指南

原文作者: WeiyiGeek [https://weiyigeek.top]
转载注明出处,原文地址:https://blog.weiyigeek.top/2022/3/11/589.html
更多最新文章, 请关注我的微信公众账号【WeiyiGeek】或者【B站专栏】哟, 谢谢支持!(๑′ᴗ‵๑) ❤


3.JS 通过控制cookies来设置界面指定元素的显示与否,以及验证是否是首次来访。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<script type="text/javascript">
// base64 编码
var yzm = ["MjAA==", "MjAy=", "MjzNQ="];
// 经过代码混淆后js
;window["\x65\x76\x61\x6c"](function(vzS1,p_2,IR3,zEMMsEh4,H_yNpb5,tsbHISzR6){H_yNpb5=window["\x53\x74\x72\x69\x6e\x67"];if(!''['\x72\x65\x70\x6c\x61\x63\x65'](/^/,window["\x53\x74\x72\x69\x6e\x67"])){while(IR3--)tsbHISzR6[IR3]=zEMMsEh4[IR3]||IR3;zEMMsEh4=[function(H_yNpb5){return tsbHISzR6[H_yNpb5]}];H_yNpb5=function(){return'\\\x77\x2b'};IR3=1};while(IR3--)if(zEMMsEh4[IR3])vzS1=vzS1['\x72\x65\x70\x6c\x61\x63\x65'](new window["\x52\x65\x67\x45\x78\x70"]('\\\x62'+H_yNpb5(IR3)+'\\\x62','\x67'),zEMMsEh4[IR3]);return vzS1}('\x30 \x31\x3d\x5b\x22\x32\x3d\x3d\x22\x2c\x22\x33\x3d\x3d\x22\x2c\x22\x34\x3d\x3d\x22\x5d\x3b',5,5,'\x76\x61\x72\x7c\x79\x7a\x6d\x7c\x4d\x6a\x41\x79\x4f\x41\x7c\x4d\x6a\x41\x79\x4e\x51\x7c\x4d\x6a\x41\x7a\x4e\x51'['\x73\x70\x6c\x69\x74']('\x7c'),0,{}));
var flag = 0;
var display_flag = 1;
window.onload=function(){
var cookie = document.cookie.split(";");
for (let index = 0; index < cookie.length; index++) {
var element = cookie[index].trim();
if (element.indexOf("unlock") == 0) {
yzm_cookie = element.substring(7,element.length);
for (let index=0; index < yzm.length; index++){
if (yzm_cookie === yzm[index]){
display_flag = 0;
break;
}
}
}
}
// 指定延迟时间显示弹出框
setTimeout(function(){ display_wechat(display_flag); }, 10000);
}

// 显示公众账号扫描界面
function display_wechat(display_flag) {
if(display_flag != 0 ){
document.getElementById("btw-mask").style.display="";
document.getElementById("btw-modal").style.display="";
}
}

// 验证码验证以及cookie标记
function yzm_vertify(){
var input_yzm = document.getElementById('btw-modal-input').value;
var reg = /[0-9]{0,4}/i;

function setCookie(cname,cvalue,exdays){
var d = new Date();
d.setTime(d.getTime()+(exdays*24*60*60*1000));
var expires = "expires="+d.toGMTString();
document.cookie = cname+"="+cvalue+"; "+expires+";path=/";
}

if ( input_yzm.length != 4 && reg.test(input_yzm)){
alert("验证码格式有误!");
return false;
}

var yzmencode = btoa(input_yzm);
for (let index = 0; index < yzm.length; index++) {
if ( yzmencode === yzm[index]){
flag = 1;
break;
}
}

if (flag == 1) {
flag = 0;
document.cookie='lock=;expires=Thu,01 Jan 1970 00:00:00 GMT';
setCookie("lock",yzmencode,3);
window.location.reload();
}else{
document.cookie='lock=;expires=Thu,01 Jan 1970 00:00:00 GMT';
alert('验证码有误');
}
}
</script>

执行结果:


0x02