webpack打包是前端js模塊化壓縮打包常用的手段访敌。同時對于后端的爬蟲調(diào)試有著一下困擾寺旺。
簡單的認識下:https://zhuanlan.zhihu.com/p/79706247 原理性知識。
1阻塑、webpack打包的特征
定義上來說:自執(zhí)行(例:!funtcion)函數(shù)的外邊一個大的數(shù)組。
舉例說明:
1渤昌、函數(shù)數(shù)值在自執(zhí)行的函數(shù)后邊(特征代碼和上邊原理鏈接有類似的代碼地方)
!function(t) {
function e(e) {
for (var i, o, s = e[0], l = e[1], u = e[2], h = 0, d = []; h < s.length; h++)
o = s[h],
Object.prototype.hasOwnProperty.call(r, o) && r[o] && d.push(r[o][0]),
r[o] = 0;
for (i in l)
Object.prototype.hasOwnProperty.call(l, i) && (t[i] = l[i]);
for (c && c(e); d.length; )
d.shift()();
return a.push.apply(a, u || []),
n()
}
function n() {
for (var t, e = 0; e < a.length; e++) {
for (var n = a[e], i = !0, s = 1; s < n.length; s++) {
var l = n[s];
0 !== r[l] && (i = !1)
}
i && (a.splice(e--, 1),
t = o(o.s = n[0]))
}
return t
}
var i = {} , r = {15: 0}, a = [];
function o(e) {if (i[e])return i[e].exports;var n = i[e] = {
i: e,l: !1,exports: {}};return t[e].call(n.exports, n, n.exports, o),n.l = !0,n.exports}
o.m = t,o.c = i,o.d = function(t, e, n) {o.o(t, e) || Object.defineProperty(t, e, {enumerable: !0,
get: n })} ,o.r = function(t) {"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {value: "Module"}),Object.defineProperty(t, "__esModule", {value: !0 })},
o.t = function(t, e) {
if (1 & e && (t = o(t)),8 & e)return t; if (4 & e && "object" == typeof t && t && t.__esModule)return t;var n = Object.create(null); if (o.r(n),Object.defineProperty(n, "default", {enumerable: !0,value: t }),2 & e && "string" != typeof t)for (var i in t)o.d(n, i, function(e) {return t[e]}.bind(null, i));return n },o.n = function(t) {var e = t && t.__esModule ? function() {return t.default}: function() {return t};return o.d(e, "a", e),e},o.o = function(t, e) {return Object.prototype.hasOwnProperty.call(t, e)},o.p = "http://bgcdn.qixin.com/pcweb/";
var s = window.webpackJsonp = window.webpackJsonp || []
, l = s.push.bind(s);s.push = e, s = s.slice();for (var u = 0; u < s.length; u++) e(s[u]);
var c = l;a.push([2250, 0]),n()}([function1(), function2()])
2独柑、函數(shù)的列表會單獨的生成一個文件夾忌栅,自執(zhí)行的入口在其他文件索绪。
(window.webpackJsonp = window.webpackJsonp || []).push([[0], {1:function1(), 2:function2()}
總結(jié):
webpack打包后的代碼有一個在自執(zhí)行函數(shù)內(nèi)的入口,這個入口可能會在函數(shù)數(shù)組上邊或者其他文件夾瑞驱。
2钱烟、如何找到自執(zhí)行入口
對于上邊第一種,我們很簡單的就能看到自執(zhí)行函數(shù)在上邊拴袭。但是對于第二種拥刻,我們需要在執(zhí)行的地方打斷點調(diào)試父泳。
如:
點擊定位位置惠窄,就能出來函數(shù)的執(zhí)行位置。
3楞卡、數(shù)組內(nèi)函數(shù)的運行流程
代碼解釋下:
1747: function(t, e, n) {
t.exports = n(1843)
},
1748: function(t, e, n) {
"use strict";
t.exports = function(t, e) {
return function() {
for (var n = new Array(arguments.length), r = 0; r < n.length; r++)
n[r] = arguments[r];
return t.apply(e, n)
}
}
},
1、他們擁有相同的參數(shù)淘捡,這些參數(shù)在不同的執(zhí)行階段(不同函數(shù)內(nèi))焦除,參數(shù)的值是不同的作彤,但是大部分是可能摸索的,比如:我找的headers中的加密值在t中宦棺,我就會側(cè)重跟蹤t的值
2瓣距、這些函數(shù)的執(zhí)行都是需要經(jīng)過執(zhí)行器黔帕,可以簡單的看下代咸,執(zhí)行器內(nèi)一般都為x.call(c,e,n)類型。都是經(jīng)過執(zhí)行器然后用call執(zhí)行函數(shù)成黄。
重點:某些網(wǎng)站呐芥,如上圖中t.exports我們可以顯性的體會到它是暴露模塊,但是奋岁,這種語法還是真沒見過哈哈思瘟,它return上邊的值是打不住斷點的,調(diào)用函數(shù)一般執(zhí)行的都是exports闻伶,可能我還沒看明白滨攻。
4、如何調(diào)試
首先說蓝翰,js文件會在瀏覽器進行緩存光绕,對于同一個界面中,進行的xhr請求不會出現(xiàn)二次加載的情況畜份。打包后的代碼塊可能不會進行二次加載停蕉,如上圖中在11451打斷點是不會斷著慧起,這就會影響逆向調(diào)試。
但是我們對加密部分的調(diào)試還是會正常進行的屈尼,相對來說麻煩了一點甲捏。
圖上示例網(wǎng)站:aHR0cHM6Ly93d3cucWl4aW4uY29tLw==
實戰(zhàn):鏈接或 http://www.reibang.com/p/5c42730a4e84