webpack打包是前端js模块化压缩打包常用的手段。同时对于后端的爬虫调试有着一下困扰。
简单的认识下:https://zhuanlan.zhihu.com/p/79706247 原理性知识。
1、webpack打包的特征
定义上来说:自执行(例:!funtcion)函数的外边一个大的数组。
举例说明:
1、函数数值在自执行的函数后边(特征代码和上边原理链接有类似的代码地方)
!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 = "//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、函数的列表会单独的生成一个文件夹,自执行的入口在其他文件。
(window.webpackJsonp = window.webpackJsonp || []).push([[0], {1:function1(), 2:function2()}
总结:
webpack打包后的代码有一个在自执行函数内的入口,这个入口可能会在函数数组上边或者其他文件夹。
2、如何找到自执行入口
对于上边第一种,我们很简单的就能看到自执行函数在上边。但是对于第二种,我们需要在执行的地方打断点调试。
如:
点击定位位置,就能出来函数的执行位置。
3、数组内函数的运行流程
代码解释下:
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、他们拥有相同的参数,这些参数在不同的执行阶段(不同函数内),参数的值是不同的,但是大部分是可能摸索的,比如:我找的headers中的加密值在t中,我就会侧重跟踪t的值
2、这些函数的执行都是需要经过执行器,可以简单的看下,执行器内一般都为x.call(c,e,n)类型。都是经过执行器然后用call执行函数。
重点:某些网站,如上图中t.exports我们可以显性的体会到它是暴露模块,但是,这种语法还是真没见过哈哈,它return上边的值是打不住断点的,调用函数一般执行的都是exports,可能我还没看明白。
4、如何调试
首先说,js文件会在浏览器进行缓存,对于同一个界面中,进行的xhr请求不会出现二次加载的情况。打包后的代码块可能不会进行二次加载,如上图中在11451打断点是不会断着,这就会影响逆向调试。
但是我们对加密部分的调试还是会正常进行的,相对来说麻烦了一点。
图上示例网站:aHR0cHM6Ly93d3cucWl4aW4uY29tLw==
实战:链接或 https://www.jianshu.com/p/5c42730a4e84