背景
大家在學習爬蟲逆向的時候,一般都會涉及到對js源文件進行代碼扣去,但是有的時候,你最好有js基礎,能發現加密或者解密在那個位置,或者是能用python改寫js代碼,這就對個人的Javascript的能力有一定要求,用了一段時間給大家整理出來了。
本篇文章整理源:https://blog.csdn.net/qq_38490457/article/details/109257751 ,本人只把js逆向應該懂得語法寫了出來,如果大家有什么不明白的,可以去 看一下原作者。
js逆向技巧
? 調用函數時,解析器也不會檢查實參的數量,多余實參不會被賦值,如果實參的數量少于形參的數量,則沒有對應實參的形參將是undefined。
? chunk開頭的js
文件是 vue
打包后的。
? webpack
整合后的js
文件一般帶有webpack_require
等字段。
立即執行函數:
(function () {alert("我是一個匿名函數");
})();
concat():
連接數組,使數組增長
var arr = ["孫悟空", "豬八戒", "沙和尚"];
var arr2 = ["白骨精", "玉兔精", "蜘蛛精"];
var arr3 = ["二郎神", "太上老君", "玉皇大帝"];
var result = arr.concat(arr2, arr3, "牛魔王", "鐵扇公主");
console.log(result);
join():
數組連接符,間隔符
var arr = ["孫悟空", "豬八戒", "沙和尚"];
var result = arr.join("@-@");
console.log(result);
call和apply:
call(對象,參數) apply(對象,參數)
person.sayHello.call(person, "Hello"); // 輸出:Hello, John
person.sayHello.apply(person, ["Hello"]); // 輸出:Hello, John
Date:
var date = new Date();
console.log(date);
console.log(date.getFullYear());//獲取當前日期對象的年份(四位數字年份)
console.log(date.getMonth());//獲取當前日期對象的月份(0 ~ 11)
console.log(date.getDate());//獲取當前日期對象的日數(1 ~ 31)
console.log(date.getHours());//獲取當前日期對象的小時(0 ~ 23)
console.log(date.getMinutes());//獲取當前日期對象的分鐘(0 ~ 59)
console.log(date.getSeconds());//獲取當前日期對象的秒鐘(0 ~ 59)
console.log(date.getMilliseconds());//獲取當前日期對象的毫秒(0 ~ 999)
隨機數:
/*隨機數*/
//Math.random():可以用來生成一個0-1之間的隨機數
//生成一個0-x之間的隨機數:Math.round(Math.random()*x)
//生成一個x-y之間的隨機數:Math.round(Math.random()*(y-x)+x)
console.log(Math.round(Math.random() * 10)); //生成一個0-10之間的隨機數
console.log(Math.round(Math.random() * (10 - 1) + 1)); //生成一個1-10之間的隨機數
字符串操操作:
concat
字符串連接concat
var str = "Hello,World!";
console.log(str.concat("你好,", "世界!"));
slice:
- 第一個參數:開始位置的索引(包括開始位置)
- 第二個參數:結束位置的索引(不包括結束位置),如果省略第二個參數,則會截取到后邊所有的
var str = "Hello,World!";
var result = str.slice(1, 4);
console.log(result);
result = str.slice(1);
console.log(result);
result = str.slice(1, -1);
console.log(result);
substr
子串:參數:
- 第一個參數:截取開始位置的索引
- 第二個參數:截取的長度
var str = "Hello,World!";
var result = str.substr(6, 6);
console.log(result);
split
字符串拆分:
? 該方法可以將一個字符串拆分為一個數組,需要一個字符串作為參數,將會根據該字符串去拆分數組
var str = "Hello,World!";
var result = str.split(",");
console.log(result);
字符串大小寫轉化:
var str = "Hello,World!";
var result = str.toUpperCase();
var result = str.toLowerCase();
正則:
創建方式一:
var 變量名 = new RegExp(“正則表達式”,“匹配模式”);
匹配模式:
- i:忽略大小寫
- g:全局匹配模式
- ig:忽略大小寫且全局匹配模式
// 這個正則表達式可以來檢查一個字符串中是否含有a
var reg = new RegExp("ab", "i");
var str = "Abc";
var result = reg.test(str);
console.log(result);
創建方式二:
var 變量名 = /正則表達式/匹配模式;
匹配模式:
-
i:忽略大小寫
-
g:全局匹配模式
-
m:執行多行匹配
-
[a-z]:任意小寫字母
-
[A-Z]:任意大寫字母
-
[A-z]:任意字母
-
[0-9]:任意數字
search() 返回第一個出現的位置,沒有則返回-1
match() 找到第一個符合要求的內容,設置匹配模式為 g ,可以將所有的匹配出來
replace( ) 默認只會替換第一個 設置全局匹配替換全部
var result = str.search(/a[bef]c/);
var result = str.match(/[a-z]/ig);
var result = str.replace(/[a-z]/gi, "@_@");
正則量詞:
-
{n}
:正好出現n次 -
{m,}
:出現m次及以上 -
{m,n}
:出現m-n次 -
+
:至少一個,相當于{1,} -
*
:0個或多個,相當于{0,} -
?
:0個或1個,相當于{0,1} -
^
:表示開頭,注意它在[^字符序列]
表達的意思不一樣 -
$
:表示結尾 -
[^a-z]:除了任意小寫字母
-
[^A-Z]:除了任意大寫字母
-
[^A-z]:除了任意字母
-
[^0-9]:除了任意數字
轉義字符:
\.
:表示.
\\
:表示\
泛指:
\w
:任意字母、數字、,相當于[A-z0-9]\W
:除了字母、數字、,相當于[^A-z0-9]\d
:任意的數字,相當于[0-9]
\D
:除了任意的數字,相當于[^0-9]
\s
:空格\S
:除了空格\b
:單詞邊界\B
:除了單詞邊界
案例:
除去空格:
var str = " hello xxxxx "
var reg = /^\s*|\s*$/g;
console.log(str);
str = str.replace(reg, "");
console.log(str);
檢驗單詞:
var str = "hello child"
var reg = /\bchild\b/;
console.log(reg.test(str));
檢測手機號:
var phoneStr = "15131494600";
var phoneReg = /^1[3-9][0-9]{9}$/;
console.log(phoneReg.test(phoneStr));
DOM節點
獲取標簽:
- getElementById()
- getElementsByTagName()
- getElementsByClassName()
- querySelector( ) css選擇器
- querySelectorAll(" ")
獲取值:
? 方法 描述
元素節點.innerText 獲取 HTML 元素的 inner Text。
元素節點.innerHTML 獲取 HTML 元素的 inner HTML。
元素節點.屬性 獲取 HTML 元素的屬性值。 a.href
元素節點.getAttribute(attribute) 獲取 HTML 元素的屬性值。 a.getAttribute(“href”)
元素節點.setAttribute(attribute, value) 改變 HTML 元素的屬性值。
元素節點.style.樣式 獲取 HTML 元素的行內樣式值。
<script>var box = document.getElementById("box");console.log(box.style.width);
</script>
<script>/*通用的獲取元素樣式的方法*/function getStyle(obj, name) {if (window.getComputedStyle) {//正常瀏覽器的方式,具有getComputedStyle()方法return getComputedStyle(obj, null)[name];} else {//IE8的方式,沒有getComputedStyle()方法return obj.currentStyle[name];}}var box = document.getElementById("box");console.log(getStyle(box, "width"));console.log(getStyle(box, "height"));console.log(getStyle(box, "background-color"));
</script>
//編寫一段兼容性代碼,用來獲取任意標簽的文本內容
<script>var a = document.getElementById("a");console.log(getInnerText(a));/*獲取任意標簽的內容*/function getInnerText(element) {// 判斷瀏覽器是否支持textContent,如果支持,則使用textContent獲取內容,否則使用innerText獲取內容。if(typeof element.textContent == "undefined") {return element.innerText;} else {return element.textContent;}}
</script>
修改 HTML 元素
方法 描述
document.createElement(element) 創建 HTML 元素節點。
document.createAttribute(attribute) 創建 HTML 屬性節點。
document.createTextNode(text) 創建 HTML 文本節點。
元素節點.removeChild(element) 刪除 HTML 元素。
元素節點.appendChild(element) 添加 HTML 元素。
元素節點.replaceChild(element) 替換 HTML 元素。
元素節點.insertBefore(element) 在指定的子節點前面插入新的子節點。
DOM事件
窗口事件:
屬性 | 描述 |
---|---|
onblur | 當窗口失去焦點時運行腳本 |
onfocus | 當窗口獲得焦點時運行腳本。 |
onload | 當文檔加載之后運行腳本。 |
onresize | 當調整窗口大小時運行腳本 |
onstorage | 當 Web Storage 區域更新時(存儲空間中的數據發生變化時)運行腳本。 |
<script>window.onblur = function () {console.log("窗口失去焦點");};
</script>
<script>window.onfocus = function () {console.log("窗口獲取焦點");};
</script>
表單事件:
屬性 | 描述 |
---|---|
onblur | 當元素失去焦點時運行腳本 |
onfocus | 當元素獲得焦點時運行腳本。 |
onchange | 當元素改變時運行腳本。 |
oninput | 當元素獲得用戶輸入時運行腳本。 |
oninvalid | 當元素無效時運行腳本。 |
onselect | 當選取元素時運行腳本。 |
onsubmit | 當提交表單時運行腳本。 |
<script>var textInput = document.getElementById("text");
/* 當文本框獲取焦點,文本框背景為紅色 */
textInput.onfocus = function () {this.style.background = "red";
};/* 當文本框失去焦點,文本框背景為綠色 */
textInput.onblur = function () {this.style.background = "green";
};
this就是調用者,誰調用就是誰。
BOM事件
就是 broswer object model 瀏覽器對象,瀏覽器自帶的對象有 window,navigate,loaction,history,screen ,這個地方很重要,為什么需要補環境,因為我們的使用nodejs模擬瀏覽器執行js,但是node的環境是沒有這些對象的。
Window對象
警告框
window.alert("sometext");
alert("sometext");
確認框
window.confirm("sometext");
confirm("sometext");
如果您希望用戶驗證或接受某個東西,則通常使用“確認”框。
當確認框彈出時,用戶將不得不單擊“確定”或“取消”來繼續進行。
如果用戶單擊“確定”,該框返回 true。如果用戶單擊“取消”,該框返回 false。
提示框
window.prompt("sometext","defaultText");// sometext提示詞 default默認值
如果用戶單擊“確定”,該框返回輸入值。如果用戶單擊“取消”,該框返回 NULL。
var person = prompt("請輸入您的姓名", "比爾蓋茨");
if (person != null) {console.log(person);
}
定時事件
-
setTimeout(function, milliseconds)
在等待指定的毫秒數后執行函數。
-
setInterval(function, milliseconds) 單位是毫秒
等同于 setTimeout(),但持續重復執行該函數。
-
setInterval() 方法:定時器
window.setInterval(function, milliseconds)
Navigate對象
? 獲取UA偽裝:navigator.userAgent
Location
console.log(location); //輸出location對象
console.log(location.href); //輸出當前地址的全路徑地址
console.log(location.origin); //輸出當前地址的來源
console.log(location.protocol); //輸出當前地址的協議
console.log(location.hostname); //輸出當前地址的主機名
console.log(location.host); //輸出當前地址的主機
console.log(location.port); //輸出當前地址的端口號
console.log(location.pathname); //輸出當前地址的路徑部分
console.log(location.search); //輸出當前地址的?后邊的參數部分
跳轉:location.assign(“https://www.baidu.com”)
刷新:location.reload(true)
HIstory對象
退回到上一個頁面:history.back();
跳轉到下一個頁面:history.forward();
異常處理:
try {// 可能發生異常的代碼
} catch (error) {// 發生錯誤執行的代碼
} finally {// 無論是否出錯都會執行的代碼
}
eval:
eval(”字符串“) eval會執行js代碼
eval("alert('Hello')");
JSON:
在JSON中,每一個數據項,都是由一個鍵值對組成的,但是鍵必須是字符串,且由雙引號包圍,而值必須是以下數據類型之一:
- 字符串(在 JSON 中,字符串值必須由雙引號編寫)
- 數字
- 對象(JSON 對象) { }
- 數組 [ ]
- 布爾
- null
JSON.parse()
? 當你有一個包含JSON字符串的變量時,你可以使用JSON.parse()
將其轉換為JavaScript對象。
var jsonString = '{"name":"John","age":30,"city":"New York"}';
var jsonObject = JSON.parse(jsonString);
console.log(jsonObject.name); // 輸出:John
console.log(jsonObject.age); // 輸出:30
console.log(jsonObject.city); // 輸出:New York
JSON.stringify()
? jsonString
將成為一個包含轉換后的JSON字符串的變量:
var data = { name: "John", age: 30, city: "New York" };
var jsonString = JSON.stringify(data);
console.log(jsonString); //{"name":"John","age":30,"city":"New York"}
console.log(data) //{ name: 'John', age: 30, city: 'New York' }
AJAX:
創建 XMLHttpRequest :
variable = new XMLHttpRequest();//所有現代瀏覽器
兼容所有瀏覽器的寫法:
var xhttp;
if (window.XMLHttpRequest) {xhttp = new XMLHttpRequest();
} else {// code for IE6, IE5xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
注意 send()這個,很多XHR頁面都有這個方法。
GET請求
users.json:
[{"name":"孫悟空","age":18,"gender":"男"},{"name":"豬八戒","age":19,"gender":"男"},{"name":"唐僧","age":20,"gender":"男"},{"name":"沙和尚","age":21,"gender":"男"}
]
index.html:
//步驟一:創建異步對象
var ajax = new XMLHttpRequest();
//步驟二:參數一是請求的類型,參數二是需要發送數據的地址
ajax.open("get", "users.json");
//步驟三:發送請求
ajax.send();
//步驟四:注冊事件 onreadystatechange 狀態改變就會調用
ajax.onreadystatechange = function () {if (ajax.readyState == 4 && ajax.status == 200) {//步驟五:如果能夠進到這個判斷,說明數據完美的回來了,并且請求的頁面是存在的console.log(ajax.responseText);//輸入響應的內容}
};
POST請求:
users.json:
[{"name":"孫悟空","age":18,"gender":"男"},{"name":"豬八戒","age":19,"gender":"男"},{"name":"唐僧","age":20,"gender":"男"},{"name":"沙和尚","age":21,"gender":"男"}
]
index.html:
//步驟一:創建異步對象
var ajax = new XMLHttpRequest();
//步驟二:設置請求的類型及數據所在的地址,注意:post請求一定要添加請求頭才行不然會報錯
ajax.open("post", "users.json");
//添加請求頭
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//步驟三:發送請求
ajax.send();
//步驟四:注冊事件 onreadystatechange 狀態改變就會調用
ajax.onreadystatechange = function () {//步驟五:如果能夠進到這個判斷,說明數據完美的回來了,并且請求的頁面是存在的if (ajax.readyState == 4 && ajax.status == 200) {console.log(ajax.responseText);//輸入響應的內容}
};
整合get和post:
var Ajax = {get: function (url, fn) {var xhr = new XMLHttpRequest();xhr.open('GET', url, true);xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304) {fn.call(this, xhr.responseText);}};xhr.send();},post: function (url, data, fn) {var xhr = new XMLHttpRequest();xhr.open("POST", url, true);xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xhr.onreadystatechange = function () {if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {fn.call(this, xhr.responseText);}};xhr.send(data);}
};// 演示GET請求
Ajax.get("users.json", function (response) {console.log(response);
});// 演示POST請求
Ajax.post("users.json", "", function (response) {console.log(response);
});
Cookie:
? 保存在本地的用戶信息,以后發送請求會攜帶cookie向服務器發送請求,這樣用戶就不用輸入相關信息了。
document.cookie = "username=zhangsan";//創建一個cookie
var cookies = document.cookie;
console.log(cookies);
cookie中的expires:
? 即過期時間,過期后自動清除。
document.cookie = "username=zhangsan; expires=Thu, 18 Dec 2043 12:00:00 GMT";
cookie中的path:
? 即可以使用 path 參數告訴瀏覽器 cookie 的路徑,/表示當前頁面
document.cookie = "username=zhangsan; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";
ES6新語法:
反引號(`):
// `` 用于多行字符串文本
let str = `<ul><li>沈騰</li><li>瑪麗</li><li>魏翔</li><li>艾倫</li></ul>`;
console.log(str);
字符串格式化:
//${變量} 表示占位符
let name = '小可愛';
let result = `歡迎${name}訪問我的文章`;
console.log(result);