1、解决 webpack-dev-server 不能使用 IP 访问
(如mac下虚拟中通过ip访问, 通过host可以访问mac下ip, 但webpack启动到dev server的ip, windows访问不到)
解决:
第一种方法:
webpack.dev.conf.js
const HOST = '192.168.x.xx:8080
第二种方法:
package.json
“dev”: “webpack-dev-server --inline --progress --config build/webpack.dev.conf.js”
// 在这句话里面添加参数 --host 0,0,0,0
“dev”: “webpack-dev-server --inline –host 0.0.0.0 --progress --config build/webpack.dev.conf.js”
// 注: 添加后会自动打开0.0.0.0:8080这样的地址
2、package-lock.json的作用,如何更新package.json\package-lock.json的组件版本
package.json // 只会锁定x这样的大版本,可能按照自动更新
package-lock.json // 锁y.z这样的小版本,所以按照更细需要按照精确到x.y.z
npm install [email protected] // 本地会更新package.json与package-lock.json
更新组件的时候使用npm install [email protected],会同时更新package.json与package-lock.json
3、vscode图标在mac的dock(程序坞)上不显示
打开终端输入killall Dock后就有了
4、连过secoclient类似的后mac无法正常上网
在本机网络加了一些dns使得用法无法正常访问,清掉后可恢复;
5、解决VS Code打开新的文件会覆盖窗口中的原文件问题
VS Code单击文件默认覆盖,这个是“预览模式”,所以再单击其他文件时,会覆盖当前打开的文件。
当你双击你想要打开的文件就会字啊新窗口打开新文件,
你也可以在setting中修改除掉预览模式,预览模式是现在各类编辑器的默认功能,如果你实在不喜欢,可以关掉的,看下面:
给你配置settings.json里加一条:
"workbench.editor.enablePreview": false
6、数据库事务
批量执行sql命令,要么全部执行,要么全部不执行,遇到回滚,所有操作回到之前操作, 命令大致如下:
mysql> begin; # 开始事务
Query OK, 0 rows affected (0.00 sec)
mysql> insert into runoob_transaction_test value(5); // 执行插入
Query OK, 1 rows affected (0.01 sec)
mysql> insert into runoob_transaction_test value(6); // 执行插入
Query OK, 1 rows affected (0.00 sec)
mysql> commit; # 提交事务
Query OK, 0 rows affected (0.01 sec)
7、js三种加载方式
js引擎与渲染引擎,js与dom css之前会存在互斥执行,dom遇到js阻塞渲染(由于浏览器不知道js会带来什么操作,担心不阻止会带来混乱,所以js执行停顿),执行完后交给dom。
但人为是可以区分js执行的操作的,可以通过几种js加载方式以做区分,
1)、js同步加载
2)、async异步加载,异步加载完js,马上就会执行
// 可以视js对dom无影响时使用
3)、defer异步加载,异步加载完js,dom解析完成domContented后执行。
// 如果js对dom有影响的操作时,使用
可以改善页面渲染过程的执行性能
8、为什么TCP/IP一定要3次握手,4次挥手,2次不行吗
3次握手,
client -> 发布SYN,携带一个生成的seq序列号, ack,表示想要与服务端建立连接
server -> 收到SYN回复ACK确认, ack + 1,同样携带一个seq序列号,表示确认收到客户端连接,客户端是否准备好?
client -> 确认报文的ACK,ack,TCP建立连接,客户端进入已连接状态;
为什么不能2次呢,服务器收到后就建立连接,很有可能网络传输长时间才到server,然后确认收到客户端请求,但客户端表示不会理睬server确认信息,server资源一直消耗等待client连接的传输;
4次挥手,
1次、客户端发出释放报文,停止发送数据,发送FIN和ACK码不是一起发的,
2次,服务端收到客户端释放报文后,回复确认ACK, 但不发送FIN, 还不可以立即关闭,还需等待可能部分数据传输完毕,
3次,服务端数据发送完毕后,回复FIN,ACK,
4次,客户端接收到,ACK确认正常关闭
Q:正常TCP连接过程,客户端突然崩了?
服务端有个保活时间,每次收到客户端消息复位计时,一般为2小时,超过了就断开连接;
SYN(DDOS攻击)
占用与服务端传输队列,超时前不释放连接资源,导致服务崩溃;
9、事件循环
Q: 异步更新dom是放在macro(setTimeout)还是micro(Promise, nextTick)中呢?
script本身是一个宏任务,本次执行完,执行遇到微任务Promise,执行后有一次render,
如果task放入setTimeout中,task只能在下一次更新执行, 放在微任务micro(Promise, nextTick)更佳,
// dom更新时间点,尽可能的靠近渲染时机
10、浏览器缓存
// 大部分我们讲的浏览器缓存简单地理解为"HTTP缓存",但其实浏览器有4种缓存
1)、Memory Cache
from memory cache
2)、Service Worker Cache
Service Worker Cache
Server Worker 对协议是有要求的,必须以 https 协议为前提。
Service Worker会监听install事件,安装cache;
Service Worker会监听所有的网络请求,网络请求的产生触发的是fetch事件,比对cache;在cache的返回,不在的发请求,存储起来;
3)、HTTP Cache
常称为浏览器缓存
4)、Push Cache
HTTP2 的新特性
Push Cache 是缓存的最后一道防线。浏览器只有在 Memory Cache、HTTP Cache 和 Service Worker Cache 均未命中的情况下才会去询问 Push Cache。
Push Cache 是一种存在于会话阶段的缓存,当 session 终止时,缓存也随之释放。
no-store与no-cache:
no-cache, 只询问服务器缓存
no-store, 服务器缓存都不询问,完整的请求响应
public 与 private:
是针对资源是否能够被代理服务缓存而存在的一组对立概念。
(默认private: 仅支持浏览器缓存)
etag与last modified:
etag基于文件内容编码,如果内容发生改变即重新请求资源,服务器重新发送etag;
last modified基于文件修改时间,
1)如果文件内容没有改变,但编辑时间变了也会重新请求;
2)如果修改时间过快在100ms以内,last modified有可能检测不到,last modified是以s为单位的。
etag与last modified同时存在下,会以etag为准;
11、react和vue的选择对比
灵活,可重用,可扩展性,seo,单向数据流downloading使较大数据块不受影响,依赖文档对象模块,虚拟dom ui存在内存做dom对比,明确的生命周期xml同时使用js和html,逻辑标记一体高度依赖函数,数据流单向flux/redux mvc很好的替代方案,扩展性多在增强组件,重新渲染和优化:尝试更改组件状态,则会更改整个组件层次结构,意味着子组件每次加新功能属性将重新排列,
vue开发时间学习曲线短,标记逻辑分开传统html开发,数据管理vuex很好的集成于vue,需要的时候添加组件可扩展性插件形式vue.use平滑集成不会扰乱系统,重新渲染和优化:允许系统保留组件更改和其他依赖记录从而相应地渲染。
12、每种工具都有其用途,了解不同的工具也确实是件好事。
如果你手里有一把锤子,所有东西看上去都像钉子。—— 亚伯拉罕·马斯洛
使用一些库时你需要考虑引入它们的时间成本,还要考虑下面的几个问题:
我将要去解决什么问题?
项目能否长久的受益于这个库吗?
React 本身是不是已经提供了现成的解决方法?
13、
vue-loader处理.vue文件,vue-style-loader同style-loader,将css-loader处理完的style属性加到DOM上。
vue-style-loader打包插件,在测试环境打包使用
extract的vue-style-loader,过滤了vue下面放style的scoped,其他lang=less等继续拆出打到合并到app.css了;
ExtractTextPlugin.extract({
use: loaders,
fallback: ‘vue-style-loader’
})
14、
一、Promise的不同定义:
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'));
// 等同于
p.then(null, function (s) {
console.log(s);
});
二、Promise的then和catch是根据resolve, reject定位链式调用的:
与定义的then/catch的先后位置无关系:
then之间通过return传值,没有return就是return undefined;
catch接收入参也是靠函数;
a = new Promise(function (resolve, reject){
resolve(111);
// reject(234);
}).then(function(res){
console.log(res, 777);
return 100;
}).catch(function(err){
console.log(err, 999);
return 12;
}).then(function(res){
console.log(res, 888);
return 123;
});
//
111 777
100 888
15、mac发热CPU占用过高问题
rg进程,VSCode,rg.exe占用cpu过高,
文件->首选项->搜search.followSymlinks“改为false,
重启就好了
16、跨域
浏览器安全性策略,同源策略,协议、域名、端口号相同为同源,否则不允许跨域,最初是指cookie不能共享,由于浏览器的表单提交时不受同源策略限制的,所以为了安全性,同源策略是必要的;
解决方案:
1、设置document.domain,一级域名相同,二级域名不同的情况下,就可以共享cookie。
2、window.name,不论同源只要在同一个窗口设置了这个属性就可以传参,容量大,但是需要额外监听。
3、jsonp跨域,通过script(该标签无同源限制)向服务器发起请求,需要指定一个回调函数,服务端会将该数据放在回调函数里。只能发送get请求,优点是简单适用、支持所有的浏览器,对服务端改动非常小。
4、window.postMessage方法来跨域传送数据。
5、webSocket 是一种通信协议,不实行同源策略,在请求头中有origin属性标记了请求源,缺点是需要支持webscoket的服务器才支持。
6、CORS跨域的配置,整个通信过程都是浏览器自动完成的,不需要用户进行参与,当浏览器发现XMLHTTPRequest或原生fetch请求,会自动附加一些头信息,有时会进行一次附件的预检请求。
7、Nginx反向代理,通过Nginx解析URL地址的时候进行判断,将请求转发到具体的服务器上,这里发出的请求和真正的请求有映射关系。
8、
17、正则表达式
\w 匹配字母或数字或下划线或汉字 等价于:
[^A-Za-z0-9_]
18、资源文件下载
1)a标签:资源所在同源域名下可以下载,其他域直接打开了,
2)a标签 + download属性 / 动态添加a标签
3)考虑将资源响应头response header改成可直接下载或者将返回资源域与前端的访问页所在域一致也行而不是查看,a链接支持站点击下载,其他源跳转打开文件,如img,html,能否后端返回资源的表现为通知用户下载而不是打开。
//通知浏览器下载文件而不是打开:
Response.AddHeader("Content-Disposition", "attachment; filename=a.txt", System.Text.Encoding.UTF8));
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
2)改变资源内容域访问资源域与前端的访问页所在域一致时,a标签可直接下载
19、精准安装包版本
npm install package --save[-dev] --save-exact
// 精确安装指定模块版本
cnpm install prettier --save-dev --save-exact
// 安装后
package.json
{
devDependencies: {
“prettier”: “2.0.5”
}
}
20、npm config
对于config这块用得最多应该是设置代理,解决npm安装一些模块失败的问题
例如我在公司内网,因为公司的防火墙原因,无法完成任何模块的安装,这个时候设置代理可以解决
npm config set proxy=http://dev-proxy.oa.com:8080
又如国内的网络环境问题,某官方的IP可能被和谐了,幸好国内有好心人,搭建了镜像,此时我们简单设置镜像
npm config set registry="http://r.cnpmjs.org"
21、代码检测与修复
husky + lint-staged + prettier + eslint // 代码提交前自动检测并修复
cnpm install prettier --save-dev --save-exact // 精准安装prettier版本包到devDependencies
// .prettierrc配置信息
{
"useTabs": false,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 100,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}
precommit中使用lint-staged钩子, 可同时执行配置信息lint-staged,
"lint-staged": {
"*.{js,jsx}": [
"prettier --write",
"eslint --fix",
"git add"
]
}
// 配置eslint,需安装一些包,会读.eslintrc配置,// 报错不修复
// 配置prettier, 需安装,会读.prettierrc配置,错误会根据.prettierrc配置信息,
// --write直接修改错格式文件进行修复
22、Vue单页面放置一段时间,load chunk failed的问题
因:
Vue的Router一般会使用import异步加载这个组件模块的资源做优化,
但有时候部署后原有还没加载的异步资源更新找不到了,
果:
这个被放置的单页面在不刷新的情况下在访问资源时所以会找不到;
Vue 解决Loading chunk (\d)+ failed问题
23、js操作dom修改高度style.height = 300需要+px, 否则不生效
dom.style.height = ‘300px’,
注:监听元素高度改变的事件,
onresize只有window有,dom元素没有
24、less下操作calc属性不起作用
需要通过转换符号,否则当表达式:
calc(100% - 130px) // -30
width:calc(~"100% - 130px");
如果要使用 Less 中的变量,两种写法如下:
@extra:50px;
width:calc(~"100% + @{extra}");
@extra:50px;
width:calc(~"100% +"(@extra)); //变量外一定要加括号,结果中会自动添加空格
25、img大小可因为网页所在容器影响大小
Img:
658 × 494 pixels (intrinsic: 1024 × 768 pixels)
658 × 821 pixels (intrinsic: 549 × 685 pixels)
// 图片如果有width: 100%,会受该网页元素限制,受img它的父元素宽度影响,因此前面一个值是它在网页呈现的大小,intrinsic为图片的原始大小;
26、npm update是更新package.json的资源包
27、npm uninstall报错
Unhandled rejection RangeError: Maximum call stack size exceededill install
node包版本与npm包版本不匹配/或npm版本过高,考虑降级npm版本,
npm install -g [email protected]
28、Object.assign
var a = {name: 123};
var b = Object.assign(a);
// b = {name: 123}
b.name = 200; // a 200
var a = {name: 123};
var b = Object.assign({}, a);
// b = {name: 123}
b.name = 200; // a 123
// 深复制且为第一层对象属性全覆盖,无法实现对象深层次继承式覆盖;
var a2 = Object.assign({},
{name: 100, obj: {age: {name: 2}, hh: 22},{name: 100, obj: {age: {name: 20}}});
// a2, {name: 100, obj: {age: {name: 20}}}
而真正的deepCopy以上3)结果应是:
// a2, {name: 100, obj: {age: {name: 20},hh: 22}}
Object.assign递归对象每一层属性值也可现在深拷贝,但耗时较长;
function toggleTodo (todos, id) {
return Object.assign({ }, todos, {
[id]: Object.assign({ }, todos[id], {
completed: !todos[id].completed
})
})
}
var nextState = toggleTodo(todos, ‘t2148bf88’)
以及除了jQuery.extend()和一些deepcopy类:deep-extend包, 其他大部分api都做不到深层次的继承拷贝;
// deep-extend
let copy = deepExtend({name: 2, age: {name: 2, age: {hh: 2}}});
let copy2 = deepExtend(copy, {name: 2, age: {name: 222}});
let copy3 = deepExtend({}, copy, {name: 2, age: {name: 222}});
copy2.name = 999;
copy3.name = 999;
console.log(copy, 'copy');
console.log(copy2, 'copy2');
console.log(copy3, 'copy3');
29、React门面处理state状态
onClose = (key) => () => {
this.setState({
[key]: false
});
};
30、lodash.js
类似underscore(_), js原生处理方法:
处理:
循环,查找,克隆等方法;
31、
===组件:hooksExampleUnstatedNext ===
// hooks 状态容器组件
import { useState, useCallback } from 'react';
import { createContainer } from "unstated-next"; // 给hooks做状态容器的,容器和容器方法都使用函数包裹对外
// 导入组件使用
import HooksExampleUnstatedNext from '../../components/hooksExampleUnstatedNext';
报错:
Hooks can only be called inside the body of a function component.
解决:
react与react-dom版本的问题,
react 16.8.0,
react-dom 16.13.1,
可以通过
32、不知道的setInterval的坑
1、不会因报错而中断执行
2、可能会因网络延迟造成请求不断排队
解决:考虑setTimeout递归调用替代setInterval
https://www.cnblogs.com/chenjg/p/9657574.html
a = function () {
setTimeout(() => {
this.a();
}, 60000);
}
33、js调试技巧
1、console.trace
获取函数调用堆栈追踪,
c = function () {
console.trace('==c==');
}
b = function () {
c();
console.log(2);
}
a = function () {
b();
console.log(1);
}
输出:// c里面调用,然后之前被b,然后是a, 最后是全局的匿名函数
==c==
c @ VM275:3
b @ VM275:6
a @ VM275:10
(anonymous) @ VM291:1
Vue触发某事件方法的trace调用栈:
=======my trace=======
lockOnlyEditRequest @ seoManage.vue?./node…=script&index=0:168
invokeWithErrorHandling @ vue.esm.js:1862
invoker @ vue.esm.js:2187
invokeWithErrorHandling @ vue.esm.js:1862
Vue.$emit @ vue.esm.js:3896
handleClick @ element-ui.common.js:9393
invokeWithErrorHandling @ vue.esm.js:1862
invoker @ vue.esm.js:2187
original._wrapper @ vue.esm.js:7564
Vue触发mounted方法的trace调用栈:
====mounted call====
mounted @ seoManage.vue?./node…=script&index=0:136
invokeWithErrorHandling @ vue.esm.js:1862
callHook @ vue.esm.js:4227
insert @ vue.esm.js:3147
invokeInsertHook @ vue.esm.js:6356
patch @ vue.esm.js:6575
Vue._update @ vue.esm.js:3956
updateComponent @ vue.esm.js:4074
get @ vue.esm.js:4487
run @ vue.esm.js:4562
flushSchedulerQueue @ vue.esm.js:4318
eval @ vue.esm.js:1988
flushCallbacks @ vue.esm.js:1914
Promise.then (async)
timerFunc @ vue.esm.js:1941
nextTick @ vue.esm.js:1998
queueWatcher @ vue.esm.js:4410
update @ vue.esm.js:4552
Vue.$forceUpdate @ vue.esm.js:3977
eval @ index.js:242
eval @ index.js:240
eval @ index.js:119
eval @ seoManage.vue:43
eval @ seoManage.vue:48
./seoManage.vue @ 163.js:61
__webpack_require__ @ app.js:708
hotApply @ app.js:632
(anonymous) @ app.js:314
Promise.then (async)
hotUpdateDownloaded @ app.js:313
hotAddUpdateChunk @ app.js:290
webpackHotUpdateCallback @ app.js:32
(anonymous) @ 163.1db7c4a….hot-update.js:1
2、控制台也可以中断调试某方法
debug(car.func()); // 文件执行到这个方法时自动中断,适用于普通的js执行文件,不适合vue这种框架文件,因为控制台找不到这个调用方法;
3、querySelector使用$查找更方便,$$查找所有
4、postman很好,firefox更方便更快也可以传递一些验证cookie
5、source下的dom元素右击可以选择监听dom元素,发生某种改变或更新时发生中断
34、javascript浮点数运算的精度问题
https://www.html.cn/archives/7340
35、less只有使用了scoped才能使用/deep/,没有scoped使用/deep/失效,找不到元素
36、将函数中的this暴露指向全局window形式写法(0, fn) ({params});
(0,obj.abc) ({params});
输出: Window对象
常规函数调用this执行调用函数的对象
obj = {
abc: function () {
console.log(this);
console.log(arguments[0]);
}
}
输出: {obj: fn}
37、禁止输入框输入表情
function eventEmo () {
var html = document.getElementsByClassName('fv__ui-freetext-editor')[0].value;
var oldHtml = "";
oldHtml = html;
var reg = /[^\u0020-\u007E\u00A0-\u00BE\u2E80-\uA4CF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF\u0080-\u009F\u2000-\u201f\u2026\u2022\u20ac\r\n]/g;
if (html.match(reg)) {
html = html.replace(reg, '');
}
if (html !== oldHtml) {
document.getElementsByClassName('fv__ui-freetext-editor')[0].value = html;
}
}
$bus.$on('eventEmoRegister', () => {
if (!!document.getElementsByClassName('fv__shape-control-move-area')[0]) {
document.getElementsByClassName('fv__shape-control-move-area')[0].addEventListener('click', (e) => {
if (!!document.getElementsByClassName('fv__ui-freetext-editor')[0]) {
document.getElementsByClassName('fv__ui-freetext-editor')[0].addEventListener('input', (edi) => {
eventEmo();
}, false)
}
});
}
});
38、获取元素在页面的坐标
function getElementPosition(ele) {
var left = 0;
var top = 0;
var p = ele;
while (p !== null) {
left += p.offsetLeft;
top += p.offsetTop;
p = p.offsetParent; // 遍历相对元素的坐标
}
var pageHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
var pageWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth);
return {
left: left,
top: top,
right: pageWidth - left - ele.offsetWidth,
bottom: pageHeight - top - ele.offsetHeight,
width: ele.offsetWidth,
height: ele.offsetHeight
};
}
// 比对元素是否在页面中的坐标比对
export function elementPosDiff (pagePos, elePos) {
if (pagePos && elePos) {
if (elePos.left >= pagePos.left && elePos.top >= pagePos.top && elePos.right >= pagePos.right && elePos.bottom >= pagePos.bottom) {
return true;
}
}
return;
}
/*
1、根据当前页码判断当前页面元素去计算坐标点位;
2、计算点击控件元素坐标位置;
3、判断当前点击元素所在页面位置->使用left, top相减然后乘以倍数(实际pdf当前页文件的宽/当前页网页中的offset宽高);
4、如果超出位置或者不在当前页面就放在当前页面正中;
*/
39、测试代码的性能
Profiler, jsPerf
40、调试工具
weinre:(需手动注入一段weinre代码可调试访问页面)
MIHTOOL:(app,自己生成一个weinre代码插入页面,提供可访问调试怼weinre链接)