自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

你有用過(guò) JavaScript 中的函數(shù)劫持么?

開發(fā) 前端
函數(shù)劫持,在一個(gè)函數(shù)運(yùn)行之前就把它劫持下來(lái),添加我們想要的功能。當(dāng)這個(gè)函數(shù)實(shí)際運(yùn)行的時(shí)候,它已經(jīng)不是原本的函數(shù)了,而是被我們添加上去的功能。這也是我們常見的鉤子函數(shù)的原理之一。

什么是函數(shù)劫持

最近業(yè)務(wù)上看到一段邏輯,找了好久,沒發(fā)現(xiàn)它是怎么被觸發(fā)的,后來(lái)發(fā)現(xiàn)其實(shí)使用了函數(shù)劫持,大致如下:

// 原始函數(shù)
var saveLog = function (log) {
console.log(`我保存了日志:${log}`);
}

// 1-保存原有函數(shù)
var originSaveLog = saveLog;

// 2-改寫原有函數(shù)
saveLog = function () {
const args = Array.prototype.slice.call(arguments);
// 3-在改寫后的函數(shù)中執(zhí)行原有函數(shù)的邏輯
originSaveLog.apply(null, args);
console.log('我要劫持你這個(gè)函數(shù),用來(lái)做自己的事情');
}

saveLog('test Save Log');

大致實(shí)現(xiàn)的邏輯就是在每次調(diào)用保存日志的同時(shí)執(zhí)行自己的邏輯,比如格式化、通知等。

函數(shù)劫持,在一個(gè)函數(shù)運(yùn)行之前就把它劫持下來(lái),添加我們想要的功能。當(dāng)這個(gè)函數(shù)實(shí)際運(yùn)行的時(shí)候,它已經(jīng)不是原本的函數(shù)了,而是被我們添加上去的功能。這也是我們常見的鉤子函數(shù)的原理之一。

如上面的示例,一般函數(shù)劫持會(huì)分成三步 :

  • 使用新的變量保存被劫持函數(shù)
  • 新函數(shù)中改寫被劫持函數(shù)
  • 新函數(shù)中調(diào)用原有的函數(shù)(保存在變量中的函數(shù))

為什么可以這么做?

一開始,我看上面這段代碼還有疑惑,當(dāng)重新給 saveLog 賦值的時(shí)候,不會(huì)改變 originSaveLog 的引用指向么?事實(shí)上是不會(huì)的,只會(huì)將 saveLog 指向另外一個(gè)引用地址。

可以看下面的例子就很容易理解了:

let a = {};
let b = a;
a.name = 'Gopal';
// ture {name: 'Gopal'} {name: 'Gopal'}
console.log(b === a, a, b);

基礎(chǔ):兩個(gè)對(duì)象指向同一個(gè)地址的時(shí)候,修改某個(gè)對(duì)象的屬性,另外一個(gè)對(duì)象也會(huì)隨之變化

let a = {};
let b = a;
a = {name: 'Gopal'};
// false {name: 'Gopal'} {}
console.log(b === a, a, b);

基礎(chǔ):將新的對(duì)象賦值給對(duì)象變量的時(shí)候,該對(duì)象變量就指向了新對(duì)象的引用地址,跟舊引用切斷關(guān)聯(lián)

應(yīng)用場(chǎng)景

增強(qiáng)你的函數(shù)功能

如上面的第一個(gè)例子,在原有的函數(shù)之上,實(shí)現(xiàn)特定的邏輯。

追蹤 XSS 攻擊

一般 XSS 攻擊會(huì)先利用 alert() 等方法輸出信息進(jìn)行測(cè)試,這個(gè)時(shí)候,我們可以對(duì)原先的 alert() 進(jìn)行劫持,向其輸入追蹤信息的代碼,最后才把原函數(shù)執(zhí)行。

如下所示:

function report(caller) {
var img=new Image();
img.src=`http://www.site.com/getReport.php?caller=${encodeURIComponent(caller)}`;
}
var _alert = window.alert;
window.alert = function (s) {
// 拿到攻擊者相關(guān)信息,并上報(bào)
report(alert.caller)
_alert(s)
}
alert('test');

劫持 ajax 請(qǐng)求,實(shí)現(xiàn) mock 功能

mock.js 中,就是通過(guò)對(duì)原生的 XMLHttpRequest(或 ActiveXObject)進(jìn)行劫持,判斷有沒有找到匹配的數(shù)據(jù)模板,如果找到,則攔截 XHR 請(qǐng)求邏輯,執(zhí)行自身規(guī)則對(duì)應(yīng)的邏輯。如果未找到匹配的數(shù)據(jù)模板,則采用原生 XHR 發(fā)送請(qǐng)求。詳細(xì)代碼看這里[1]。

總結(jié)

JavaScript 中的函數(shù)劫持是一個(gè)增強(qiáng)原有函數(shù)的技巧,一般我們用來(lái)對(duì)原有的 JavaScript 全局方法做一些能力的增強(qiáng)。

參考資料

[1]這里: https://github.com/nuysoft/Mock/blob/refactoring/src/mock/xhr/xhr.js

責(zé)任編輯:武曉燕 來(lái)源: 前端雜貨鋪
相關(guān)推薦

2009-07-20 10:18:49

PHP 5.3命名空間

2022-10-17 15:47:19

JavaScript開發(fā)Web

2021-04-07 09:52:46

JavaScript函數(shù)劫持攻擊

2023-12-22 16:39:47

Java函數(shù)式接口開發(fā)

2016-09-26 17:15:51

2020-12-28 06:20:27

OptionalTryjava

2020-08-16 10:58:20

Pandaspython開發(fā)

2020-04-22 15:27:30

Vue組件項(xiàng)目

2020-11-09 07:25:20

函數(shù) JavaScript數(shù)據(jù)

2023-06-13 15:15:02

JavaScript前端編程語(yǔ)言

2023-08-30 07:27:39

2020-08-23 09:18:30

Pandas函數(shù)數(shù)據(jù)分析

2021-11-30 08:44:29

SpringRouter Func函數(shù)式接口

2022-04-08 14:45:23

JavaScript框架/前端

2021-09-07 08:33:27

JavaScript TypeScript 函數(shù)

2023-09-09 12:23:24

函數(shù)式接口程序

2017-10-26 08:53:38

前端JavaScript函數(shù)式編程

2020-01-17 20:00:25

SQL函數(shù)數(shù)據(jù)庫(kù)

2022-11-07 16:25:07

JavaScript技巧

2023-10-26 07:47:35

JavaScript代碼變量
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)