很早之前的笔记,先发出来,后面有很多没有完善起来
chrome重写js文件并替换
:第一步先添加文件夹:Sources>Overrides>Select folder for overrides;第二步去请求包Network页面选择js文件>右击Open in Sources panel>重新编辑js文件>刷新即可运行DOM断点
:右击元素attribute modifications下断点(不推荐)DOM事件下断点
:Event Listeners、点击、Canvas、load等事件断点xhr断点
:只针对xhr请求捕获异常断点
:右侧暂停按钮,勾选Pause on caught exceptions,可捕获全局断点针对静态网页
:可以用fiddler替换网页js文件,并将其中的debugger删掉针对动态网页
:
常用方式过debugger
:鼠标右击选择Never pause hereFunction原理的debugger
,可以重写函数构造器Function.prototype.constructor_bc = Function.prototype.constructor
Function.prototype.constructor = function() {
if (arguments[0] === "debugger") {}
else {
Function.prototype.constructor_bc.apply(this, arguments)
}
}
eval类型的debugger
,可以重构eval函数eval_bc = eval
eval = function(a) {
if (a === '(function() {var a = new Date(); debugger; return new Date() - a > 100;}())') {}
else {
return eval_bc(a)
}
}
(function() {var a = new Date(); debugger; return new Date() - a > 100;}())
:定时器的无限debugger,可用上面的方法,或者以下两种方法setinval_b= setInterval
setInterval = function(a, b) {
if (a.toString().indexOf('debugger') == -1) {
console.log(a);
return setinval_b(a, b)
}
}
for (var i = 1; i < 99999; i++)window.clearInterval(i);
向上找堆栈,在进入无限debugger之前打上断点将触发无限debugger的函数置空
hook之window的属性
(function() {
'use strict';
var pre = "";
Object.defineProperty(window, '_pt_', {
get: function() {
console.log('Getting window.属性');
return pre
},
set: function(val) {
console.log('Setting window.属性', val);
debugger ;
pre = val;
}
})
})();
hook之cookie
(function() {
'use strict';
var _cookie = ""; // hook cookie
Object.defineProperty(document, 'cookie', {
set: function(val) {
console.log('cookie set->', new Date().getTime(), val);
debugger;
_cookie = val;
return val;
},
get: function(val) {
return _cookie;
}
});
})()
通过Fiddler用本地js文件替换源网页的js文件
,将网页端的js文件保存到本地,并修改js内容里面想要改的地方,比如保存为ticket.js(2)数据类型:基本数据类型:字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined
);引用数据类型:对象(Object)、数组(Array)、函数(Function)
,可通过typeof()检查数据类型
(3)当你通过var声明变量时,可以使用关键词 “new” 来声明其类型
var carname=new String;
var x= new Number;
var y= new Boolean;
var cars= new Array;
var person= new Object;
(4)变量声明提前,使用var关键字声明的变量,会在所有代码执行之前被声明(但不会被赋值),但是如果声明变量不使用var关键字,则变量不会被声明提前
(5)在函数中,不使用var声明的变量都会成为全局变量
(6)对象Object:对象属性名可加双引号可不加双引号,只能是字符串,值可以是任意的数据类型
内建对象
:由ES标准中定义的对象,在任何的ES的实现中都可以使用,比如:Math,String,Number,Boolean,Function,Object宿主对象
:由JS运行环境提供的对象,目前来讲主要是浏览器提供的对象,比如BOM,DOM自定义对象
:由开发人员自定创建的对象// 定义一个对象
let obj = {hello: 'world'};
// 浅拷贝,只复制对象的内存地址,类似于指针,只要其中之一改变,则另一个也随之改变
let obj2 = obj;
// 深拷贝,完全克隆,生成一个新对象
let obj3 = JSON.parse(JSON.stringify(obj));
// 定义
let me = {
name: 'shir',
age: "18",
fullname: function() {
return
}
};
// 赋值也可以取值
me.education = 'College'
me['sex'] = '女'
me[love] = 'flower'
// 取值
console.log(Object.keys(me)) // ["name", "age", "education", "sex", "love"]
console.log(Object.values(me)) // ["shir", "18", "College", "女", "flower"]
// 删除属性
delete me.education
// 遍历
for (let key in me) {
if (me.hasOwnProperty(key)){
const value = me[key]
console.log(key, value) // name shir age 18
}
}
(7)数组Array
:值可以是任意的数据类型,map()和forEach()方法遍历数组
// 常规方式
var myCars=new Array();
myCars[0]="Saab";
myCars[1]="Volvo";
myCars[2]="BMW";
// 简洁方式
var myCars=new Array("Saab","Volvo","BMW");
// 字面方式
var myCars=["Saab","Volvo","BMW"];
.length
,数组的追加push()
,数组的尾部删除pop()
,数组的头部增加unshift()
,数组的头部删除shift()
,数组排序sort()
,数组逆序排序reverse()
let items = [1, 2, 3, 4, 5]
console.log(items[2]); // 3
items[3] = "4shir"; // 第4个位置赋值
items.length; // 5
items.indexOf(5); // 读索引值
items.push(6); // 相当于python的append(),追加一个元素
items.pop(); // 删除最后一个元素
items.unshift("Lemon","Pineapple") // 头部增加第一个元素
items.shift(); // 删除第一个元素
items.sort(); // 正序排序
items.reverse(); // 反序排序
splice(index, 0, 元素)
与删除splice(index,个数)
let items = [1, 2, 3, 4, 5]
// 指定索引添加或删除
items.splice(
0, // 指定索引添加
0, // 不删除即为添加
"0", // 添加的元素值
);
items.splice(
0, // 指定索引删除
2, // 删除多少个
);
.map()
与.forEach()
//数组遍历方式1,map会返回新数组
var items = [1,2,3,4,5];
var result = items.map(function( value ) {
return value * 2;
});
console.log(result);
// 数组遍历方式2,forEach不会有新数组返回,也没有break和continue,可通过some和every实现
var arr = [1, 2, 3, 4, 5];
arr.forEach(function (item) {
if (item === 3) {
return; // return语句实现continue 关键字的效果:
}
console.log(item);
});
concat()
var parents = ["Jani", "Tove"];
var brothers = ["Stale", "Kai Jim", "Borge"];
var children = ["Cecilie", "Lone"];
var family = parents.concat(brothers, children); //["Jani", "Tove", "Stale", "Kai Jim", "Borge", "Cecilie", "Lone"]
(8)逗号运算符使用逗号,
,可以分割多个语句,一般在声明多个变量时使用
(9)在JS中可以使用{}来为语句进行分组
,一个{}中的语句我们称为一组语句或代码块,它们要么都执行,要么都不执行,在代码块后边就不用再写分号;了
(1)函数定义:
(2)构造函数
:使用new关键字调用的函数,最后一个位置为函数执行体,前面的位置可加形参
let sum = new Function('a', 'b', 'return a + b');
sum(1, 2)
let sayHi = new Function('console.log("Hello")');
sayHi()
function Person(){
this.name="小明";
this.age=18;
}
var p1=new Person();
console.log(p1, p1.name,p1.age);
(3)有名函数
:function关键字后面指定名字的,如下案例,指定函数名myNameFun
function myNameFun(a,b){
console.log(a+b)
}
myNameFun(1, 1)
(4)匿名函数
:function关键字后面没有名字的
// 匿名函数格式
function(a,b){
console.log(a+b)
}
(5)自执行函数
:顾名思义,就是立即自动执行的函数,有名函数和匿名函数都可以自执行
,举例几个匿名函数自执行的方式如下;因为js是函数作用域,所以如果想实现某个功能又不想污染全局变量的时候可以使用自执行函数
;样例见某盾core.js一个典型的实际用例,逐步调试看看就懂了
自执行方式1:变量=匿名函数(传入参数)
,把匿名函数赋给一个变量自执行,// 自执行方式1
var myNamefun = function(a,b){
console.log(a+b)
}(1,1)
自执行方式2:(匿名函数)(传入参数)
,样例如下// 自执行方式2
(function(a,b){
console.log(a+b)
})(1,1);
自执行方式3:(匿名函数(传入参数))
,样例如下(function(a,b){
console.log(a+b)
}(1,1));
!function () { /* code */ } ();
!(function () { /* code */ } )();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();
(6)箭头函数
:(参数1, 参数2, …, 参数N) => 表达式(单一)
// ES5
var x = function(x, y) {
return x * y;
}
// ES6
const x = (x, y) => x * y;
(7)函数的参数:显式参数(Parameters)与隐式参数(Arguments),JavaScript 函数有个内置的对象 arguments 对象
,argument 对象包含了函数调用的参数数组,arguments是个类数组对象; 在调用函数时浏览器每次都会传递两个隐含的参数:函数的上下文对象this、封装实参的对象arguments
funciton test(){
var m = arguments[0]; //第一个传入的参数
var n = arguments[1]; //第二个传入的参数,如果只传入一个参数,那么该值为undefined
var l = argument.length;//该值对应的函数调用时传入参数的个数
var ll = fun.length;//该值对应的函数定义的参数个数
}
(8)函数的特征熟悉
(1)作用域:在JS中一共有两种作用域,一种是全局作用域,一种是函数作用域
(2)局部作用域
:在函数内通过var声明的变量,变量为局部变量,所以只能在函数内部访问它,该变量的作用域是局部的;
(3)全局作用域
:在函数外通过var声明的变量为全部变量,不使用var声明的变量默认都是全局变量
(4)this
:表示当前对象的一个引用,不是固定不变的,它会随着执行环境的改变而改变,换言之当前谁是this的拥有者,this就指向谁
全局中的this
:全局作用域中,this指向全局对象window//在全局作用域中声明变量num
var num=1;
console.log(window.num);//1
//修改this对象身上的num属性,将num属性的值修改为2
this.num=2;
console.log(window.num);//2
console.log(this===window);//true
方法中的this
:this是调用方法的对象;在方法中,this指向该方法所属的对象,如下this指向了p1对象,因为p1对象是speak方法的所有者var p1={
name:"11",
speak:function(){
console.log("我是"+this.name); // 我是11
console.log(this===p1);//true
}
}
p1.speak();
普通函数中的this
:this永远都是window;函数的所属者默认绑定到this上,即谁拥有这个函数,即指向了window,因为在全局作用域中创建的函数都会作为window对象的方法保存function Person(){
this.name="小明";
console.log(this===window); // true
}
Person();//实际上相当于window.Person()
var p1={
friend:"小明",
speak:function(){
console.log(this===p1);//false
console.log(this===window);//true
console.log("我的朋友是"+this.friend);
//我的朋友是undefined,因为此时this指向window,
//window身上并没有friend这个属性,所以读取结果是undefined
//speak2属于全局变量,全局变量作为window对象属性保存,所以指向window
}
}
var speak2=p1.speak;
speak2();//此处相当于window.speak2()
构造函数中的this
:this是新创建的那个对象(5)call()、apply()、bind():可以强制改变函数内部this的指向
,this就是指定的那个对象;执行结果一致,如下案例this本来应该指向obj对象,但是最终指向了了obj2对象
call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,差别在于第二个以及后面的参数
call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔
,直接放到后面 obj.func.call(obj2,‘成都’, … ,’)
apply 的所有参数都必须放在一个数组里面传进去
obj.func.apply(obj2,[‘成都’, …, ])
bind 除了返回是函数以外,它的参数和 call 一样
let obj = {
name:'张三',
age:18,
func:function(fm, t){
console.log(this.name + "年龄" + this.age + "来自" + fm + "去向" + t);
}
}
let obj2 = {
name:'李四',
age:20
}
obj.func.call(obj2, '成都', '上海') //李四年龄20来自成都去向上海
obj.func.apply(obj2, ['成都', '上海']); //李四年龄20来自成都去向上海
obj.func.bind(obj2, '成都', '上海')(); //李四年龄20来自成都去向上海
(6) 关于JS中作用域的销毁和不销毁的情况总结
(1)escape()
:对普通字符串编码。unescape()
:对字符串普通解码。encodeURIComponent()
:对URL进行编码,编码范围大于encodeURI()
。decodeURIComponent()
:对URL进行解码,解码范围大于decodeURI()
(3)JSON.stringify()
:类似python的json.dumps(),将json对象转换成json字符串。 JSON.parse()
:类似python的json.loads(),将json字符串转换成json对象
(4)slice()
:不会改变原始数组,截取某段索引范围的数据 。splice()
:指定数组某个索引值是添加元素还是删除多少个元素,第二个位置参数数字代表删除多少个。substr()
: 的参数指定的是子串的开始位置和长度
(6)charCodeAt()
:返回指定位置的字符的 Unicode 编码,String.fromCharCode()
:返回Unicode编码对应的字符,charAt()
:可返回指定位置的字符
(7) Math.random,Math.ceil,Math.floor,Math.abs,Math.log
如window、navigator、location、document脱离浏览器、在外部不能直接调用,当你从全局复制js,则需要补齐环境
(4)document
document = {
write:function(){}
}
document.write.toString = function(){return "function write() { [native code] }"}
(5)html事件
WebApI
: 详细nodejsAPI
: 详细window.ActiveXObject
:用来判断浏览器是否支持ActiveX控件,只有IE才能装ActiveX插件,所以通过此方法判断是不是ie浏览器window.msCrypto
:IE11的Web Crypto位于window.msCrypto内部,而对于Firefox或Chrome,它可以在window.crypto中访问,Web Crypto提供了一些加密window.addEventListener(event, function, useCapture)
:事件监听函数,第一个参数是事件的类型 (如 “click” 或 “mousedown”),第二个参数是事件触发后调用的函数,第三个参数是个布尔值用于描述事件是冒泡(false,先内后外)还是捕获,该参数是可选的window.removeEventListener(event, function)
:移除事件监听window.localStorage
:localStorage不能被爬虫抓取到window.unload
:document.characterSet
和document.charset
:返回当前文档的字符编码requests基础代码
:至少要包含请求头、timeout,resp.json()请求头保持顺序不变
:用session.headers=headers可以防止请求头的顺序乱掉,而requests请求(由于python字典特性)会让headers的请求头乱响应请求头快速转换
,右击开发者工具,copy all as cURL, 复制到转换为python代码