目录
4、vue.js如何编译temple,获取其他引擎何如编译(art-Template)
1、协议
Http(HyperText Transfer Protocol) 超文本传输协议:用于分布式、协作式和超媒体信息系统的应用层协议
客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
2、游览器页面跳转过程
1)、URL地址的解析:一个URL包括协议,网络地址,资源路径
2)、
DNS域名解析:解析域名找到IP,通过这个IP可以找到客户端到服务器端的唯一路径.
3)、浏览器主机根据ip地址与服务器建立TCP连接(三次握手)
图文理解:
客户端:“你好,你的快递到了,人在家吗?”
服务端:“在的,送来就行。”
客户端:“好嘞。”
4)、发送HTTP请求
请求行包括请求方法、URI、HTTP版本。首部字段传递重要信息,包括请求首部字段、通用首部字段和实体首部字段。
5)、服务器处理请求
在响应结果中都会有个一个HTTP状态码
6)、断开TCP连接(4次握手)
- 客户端发起中断请求,发送
FIN
到服务端 - 服务端收到请求,可能数据还没有发完。这个时候不会关闭socket,而是回复
ACK
,告诉客户端知道了 - 客户端进入Fin_Wait状态,继续等待服务端端的
FIN
报文。服务端端发送完毕后,会向客户端发送FIN
- 客户端客服端收到后就回复
ACK
,并关闭连接
- 客户端:“兄弟,我这边没数据要传了,咱关闭连接吧。”
- 服务端:“收到,我看看我这边有木有数据了。”
- 服务端:“兄弟,我这边也没数据要传你了,咱可以关闭连接了。”
- 客户端:“好嘞。”
7)、浏览器解析文件
浏览器通过解析
HTML
,生成DOM树,解析CSS
,生成CSS规则树,然后通过DOM树和CSS规则树生成渲染树。渲染树与DOM树不同,渲染树中并没有head、display为none等不必显示的节点。
要注意的是
,浏览器的解析过程并非是串连进行的,比如在解析CSS的同时,可以继续加载解析HTML,但在解析执行JS脚本时,会停止解析后续HTML,这就会出现阻塞问题,关于JS阻塞相关问题,(js阻塞问题可以自行百度,或者等我有时间更新一篇文章,单独解释阻塞)
作者:掘金吐槽摸鱼一号
链接:https://juejin.cn/post/6844903919395536910
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
8)、浏览器布局渲染
根据渲染树布局,计算CSS样式,即每个节点在页面中的大小和位置等几何信息。HTML默认是流式布局
的,CSS和js会打破这种布局,改变DOM的外观样式以及大小和位置。这时就要提到两个重要概念:repaint(重绘)和reflow(回流)。
repaint
:屏幕的一部分重画,不影响整体布局,比如某个CSS的背景色变了,但元素的几何尺寸和位置不变。
reflow
: 意味着元件的几何尺寸变了,我们需要重新验证并计算渲染树。是渲染树的一部分或全部发生了变化。这就是Reflow,或是Layout。
此处解答参考,具体如下详情
作者:掘金吐槽摸鱼一号
链接:https://juejin.cn/post/6844903919395536910
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
3、跨域问题
4、vue.js如何编译temple,获取其他引擎何如编译(art-Template)
5、link与@important区别
本质上,这两种方式都是为了加载css文件,但还是存在细微的差别
差别1:老祖宗的差别,link属于XHTML标签,而@import完全是css提供的一种方式。
link标签除了可以加载css外,还可以做很多其他的事情,比如定义RSS,定义rel连接属性等,@import只能加载CSS。
差别2:加载顺序的差别:当一个页面被夹在的时候(就是被浏览者浏览的时候),link引用的CSS会同时被加载,而@import引用的CSS会等到页面全部被下载完再加载。所以有时候浏览@import加载CSS的页面 时会没有样式(就是闪烁),网速慢的时候还挺明显。
差别3:兼容性的差别。由于@import是CSS2.1提出的所以老的浏览器不支持,@import只有在IE5以上的才能识别,而link标签无此问题,完全兼容。
差别4:使用dom控制样式时的差别。当时用JavaScript控制dom去改变样式的时候,只能使用link标签,因为@import不是dom可以控制的(不支持)。
6、同步与异步区别
1)同步:
同步,我的理解是一种线性执行的方式,执行的流程不能跨越。一般用于流程性比较强的程序,我们做的用户登录功能也是同步处理的,必须用户通过用户名和密码验证后才能进入系统的操作。
2)异步:
异步,是一种并行处理的方式,不必等待一个程序执行完,可以执行其它的任务。在程序中异步处理的结果通常使用回调函数来处理结果。
//ajax
ajax({
url:''.
method:'',//get/post
data:'',//参数
//true请求均为异步请求。false同步请求
async:boolean,
contentType:'',
beforeSend:function,//请求钱的操作
dataType:'',
success:function,
error:function,
complete:function,//完成回掉函数
timeout:number(ms)
})
//Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中
let service = axios.create({
// `url` 是用于请求的服务器 URL
url: '/user',
// `method` 是创建请求时使用的方法
method: 'get', // 默认是 get
// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
baseURL: 'https://some-domain.com/api/',
// `transformRequest` 允许在向服务器发送前,修改请求数据
// 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
// 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
transformRequest: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对 data 进行任意转换处理
return data;
}],
// `headers` 是即将被发送的自定义请求头
headers: {'X-Requested-With': 'XMLHttpRequest'},
// `params` 是即将与请求一起发送的 URL 参数
// 必须是一个无格式对象(plain object)或 URLSearchParams 对象
params: {
ID: 12345
},
// `paramsSerializer` 是一个负责 `params` 序列化的函数
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
// `data` 是作为请求主体被发送的数据
// 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
// 在没有设置 `transformRequest` 时,必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属:FormData, File, Blob
// - Node 专属: Stream
data: {
firstName: 'Fred'
},
// `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
// 如果请求话费了超过 `timeout` 的时间,请求将被中断
timeout: 1000,
// `withCredentials` 表示跨域请求时是否需要使用凭证
withCredentials: false, // 默认的
// `adapter` 允许自定义处理请求,以使测试更轻松
// 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
adapter: function (config) {
/* ... */
},
// `auth` 表示应该使用 HTTP 基础验证,并提供凭据
// 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
responseType: 'json', // 默认的
// `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
xsrfCookieName: 'XSRF-TOKEN', // default
// `xsrfHeaderName` 是承载 xsrf token 的值的 HTTP 头的名称
xsrfHeaderName: 'X-XSRF-TOKEN', // 默认的
// `onUploadProgress` 允许为上传处理进度事件
onUploadProgress: function (progressEvent) {
// 对原生进度事件的处理
},
// `onDownloadProgress` 允许为下载处理进度事件
onDownloadProgress: function (progressEvent) {
// 对原生进度事件的处理
},
// `maxContentLength` 定义允许的响应内容的最大尺寸
maxContentLength: 2000,
// `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认的
},
// `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
// 如果设置为0,将不会 follow 任何重定向
maxRedirects: 5, // 默认的
// `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
// `keepAlive` 默认没有启用
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
// 'proxy' 定义代理服务器的主机名称和端口
// `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
// 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
proxy: {
host: '127.0.0.1',
port: 9000,
auth: : {
username: 'mikeymike',
password: 'rapunz3l'
}
},
// `cancelToken` 指定用于取消请求的 cancel token
// (查看后面的 Cancellation 这节了解更多)
cancelToken: new CancelToken(function (cancel) {
})
});
// 在实例已创建后修改默认值
service.defaults.headers.common['Authorization'] = AUTH_TOKEN;
//配置优先级(逐级递增)
// 使用由库提供的配置的默认值来创建实例
// 此时超时配置的默认值是 `0`
var instance = axios.create();
// 覆写库的超时默认值
// 现在,在超时前,所有请求都会等待 2.5 秒
instance.defaults.timeout = 2500;
// 为已知需要花费很长时间的请求覆写超时设置
instance.get('/longRequest', {
timeout: 5000
});
7、cookie,sessionStorage,localStorage的区别
特性 | cookie | localStorage | sessionStorage | indexedDB |
---|---|---|---|---|
数据生命周期 | 一般由服务器生成,可以设置过期时间 | 除非被清理,否则一直存在 | 页面关闭就清理 | 除非被清理,否则一直存在 |
数据存储大小 | 4K | 5M | 5M | 无限 |
与服务端通信 | 每次都会携带在 header,中,对于请求性能影响 | 不参与 | 不参与 | 不参与 |
游览器关闭 | 如果不设置Expires的属性那么Cookie的存活时间就是在关闭浏览器的时候。 | 游览器关闭消失 | 单游览器页面关闭消失 | IndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据 |
补充:cookie 原本并不是用来储存的,而是用来与服务端通信的
要使用cookie,页面必须在服务器中运行,直接双击打开页面无法使用cookie。
Cookie的后端
会话级别的Cookie:默认的关闭了浏览器Cookie就销毁了
持久级别的Cookie:需要设置有效时长,关闭浏览器也不会销毁的Cookie
setMaxAge(int expiry):
以秒为单位的时间,超过了该时间后Cookie会自动销毁
setMaxAge(0):
手动删除持久性的Cookie。(前提path和那么必须一致)
setPath(Stirng uri):
设置Cookie的有效路径
例如:
1)cookie.setPath("/JavaEEDemo/learn/demo");
表示JavaEEDemo项目下,learn目录下的所有servlet,都可以访问当前cookie
“/learn"或”/learn/aaa"将不能访问
2)cookie.setPath("/JavaEEDemo");
表示JavaEEDemo项目下的所有servlet都可以访问当前cookie
3)cookie.setPath("/");
表示tomcat下的所有web项目,都可以访问当前cookie
cookie的唯一表示:唯一表示:domain + path + name (类似Java中 包 + 类名)
domain 域名,不同的网站使用的是不同的域名,cookie就不同
path 路径,通过cookie.setPath()设置的内容
name cookie的名称,通过 new Cookie(name,…)确定的内容
例如:以下表示的是两个Cookie,可以同时存在
1)/web/a/b/cookieName
2)/web/acookieName
如果路径和名称一样,两个addCookie()后者将覆盖前者。HttpOnly Cookies是一个cookie安全行的解决方案。
在支持HttpOnly cookies的浏览器中(IE6+,FF3.0+),如果在Cookie中设置了"HttpOnly"属性,那么通过JavaScript脚本将无法读取到Cookie信息,这样能有效的防止XSS攻击,让网站应用更加安全。
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
/**
* Cookie工具类
*/
public class CookieUtil {
/**
* 设置HttpOnly Cookie
* @param response HTTP响应
* @param cookie Cookie对象
* @param isHTTPOnly 是否为HttpOnly
*/
public static void addCookie(HttpServletResponse response, Cookie cookie, boolean isHttpOnly) {
String name = cookie.getName();//Cookie名称
String value = cookie.getValue();//Cookie值
int maxAge = cookie.getMaxAge();//最大生存时间(毫秒,0代表删除,-1代表与浏览器会话一致)
String path = cookie.getPath();//路径
String domain = cookie.getDomain();//域
boolean isSecure = cookie.getSecure();//是否为安全协议信息
StringBuilder buffer = new StringBuilder();
buffer.append(name).append("=").append(value).append(";");
if (maxAge == 0) {
buffer.append("Expires=Thu Jan 01 08:00:00 CST 1970;");
} else if (maxAge > 0) {
buffer.append("Max-Age=").append(maxAge).append(";");
}
if (domain != null) {
buffer.append("domain=").append(domain).append(";");
}
if (path != null) {
buffer.append("path=").append(path).append(";");
}
if (isSecure) {
buffer.append("secure;");
}
if (isHttpOnly) {
buffer.append("HTTPOnly;");
}
response.addHeader("Set-Cookie", buffer.toString());
}
}
Cookie前端
1.cookie存在document.cookie中。
2.删除cookie则设置cookie的过期时间为当前时间-1。
3.设置cookie时需要对value进行编码,即使用escape函数,取出时需要进行解码,即使用unescape函数。
注:escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。
//cookie存储值
function setCookie(cName,cValue,exDays){
var d = new Date();
d.setTime(d.getTime()+(exDays*24*60*60*1000));
var expires = "expires="+d.toGMTString();
document.cookie = cName+"="+cvalue+"; "+expires;
}
//cookie读取值
function getCookie(cName){
var name = cName + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name)==0) { return c.substring(name.length,c.length); }
}
return "";
}
//检查cookie值
function checkCookie(){
var user=getCookie("username");
if (user!=""){
alert("欢迎 " + user + " 再次访问");
}
else {
user = prompt("请输入你的名字:","");
if (user!="" && user!=null){
setCookie("username",user,30);
}
}
}
//删除cookie值
function delCookie(name){
var d = new Date();
d.setTime(d.getTime() + 5*60*1000); // in milliseconds
document.cookie = 'name=;path=/;expires='+d.toGMTString()+';';
//等同于
//document.cookie = 'name=;path=/;max-age='+5*60+';';
}
localStorage (window.localStorage)
- localStorage 只能存字符串,存取 JSON 数据需配合 JSON.stringify() 和 JSON.parse()
- 遇上禁用 setItem 的浏览器,需要使用 try...catch 捕获异常
- localStorage 的使用也是遵循同源策略的
- localStorage 只支持 string 类型的存储。
localStorage 的局限
- 1、浏览器的大小不统一,并且在 IE8 以上的 IE 版本才支持 localStorage 这个属性。
- 2、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换。
- 3、localStorage在浏览器的隐私模式下面是不可读取的。
- 4、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡。
- 5、localStorage不能被爬虫抓取到。
//-------三种存储值写法---------
if(!window.localStorage){
alert("浏览器不支持localstorage");
return false;
}else{
var storage=window.localStorage;
//写入a字段
storage["a"]=1;
//写入b字段
storage.b=1;
//写入c字段
storage.setItem("c",3);
//-----三种读取方法------
//第一种方法读取
var a=storage.a;
console.log(a);
//第二种方法读取
var b=storage["b"];
console.log(b);
//第三种方法读取
var c=storage.getItem("c");
//--------清除---------
storage.clear();
//--------删除-----------
storage..removeItem(key)
//---------获取-------------
for(var i=0;i<storage.length;i++){
var key=storage.key(i);
console.log(key);
}
}
sessionStorage
sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。
----语法
//获取sessionStorage
var sessionStorage = window.sessionStorage;
//保存数据
sessionStorage.setItem("key", "value");
//读取数据
var lastName = sessionStorage.getItem("key");
//删除数据
sessionStorage.removeItem("key");
//删除所有数据
sessionStorage.clear();
indexedDB (H5新增,Web SQL)
(1)存储数据量非常大,在理论上基本上不封顶。具体的上限按照磁盘进行计算,理论上是可以磁盘空间的50%
(2)是文档型数据库,与Mongodb等类似,与常见的关系型数据库不同,不支持SQL语句查询。
(3)支持且只支持transaction事务,对保证数据安全具有重要意义,与传统数据库中的事务目的一致。
(4)遵循同源策略,所以网页只能访问同域的IndexedDB数据库,而无法访问其他域上的数据。
(5)大多数情况下API采用异步操作,以防止数据操作量大时,阻塞其他操作的进行。(同步暂时大部分的浏览器暂不支持)
(6)不是以表的形式存储数据,而是通过对象仓库存储。(可以理解为一张表,但从存储结构上并不一样)
(7)数据库除了存储字符串外,还可以存储Date, Object, Arra, File, Blob, ImageData或二进制等数据类型。
(8)能够为数据建立索引,以此提高查询数据的各方面性能。(这个非常有用,是大数据快速查找的前提)
备注:
注意indexeddb已经内置到浏览器中,无需其他依赖包和三方库。在浏览的调试情况下,本地缓存的展示位置如下图。
8、什么是闭包,为什么用闭包
闭包就是能够读取其他函数内部变量的函数,定义在一个函数内部的函数。本质上就是将函数内部和函数外部连接起来的一座桥梁。
使用闭包原理:即重用一个变量,又保护变量不被污染的一种机制。
1. 用外层函数包裹要保护的变量和内层函数。
2. 外层函数将内层函数返回到外部。
3. 调用外层函数,获得内层函数的对象,保存在外部的变量中——形成了闭包。
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
9、数组的方法
10、字符串包含判断
11、数组的去重
1)、ES6 set方法:Array.form(new Set(array))
2)、循环对比
function unique(arr){
for(var i=0; i<arr.length; i++){
for(var j=i+1; j<arr.length; j++){
if(arr[i]==arr[j]){ //第一个等同于第二个,splice方法删除第二个
arr.splice(j,1);
j--;
}
}
}
return arr;
}
12、谈谈This对象的理解
13、js如何实现继承的
1)1.原型链继承
function Parent () {
this.names = ['kevin', 'daisy'];
}
function Child () {
}
Child.prototype = new Parent();
var child1 = new Child();
child1.names.push('yayu');
console.log(child1.names); // ["kevin", "daisy", "yayu"]
var child2 = new Child();
console.log(child2.names); // ["kevin", "daisy", "yayu"]
2)借用构造函数(经典继承)
function Parent () {
this.names = ['kevin', 'daisy'];
}
function Child () {
Parent.call(this);
}
var child1 = new Child();
child1.names.push('yayu');
console.log(child1.names); // ["kevin", "daisy", "yayu"]
var child2 = new Child();
console.log(child2.names); // ["kevin", "daisy"]
3)、
14、vue首页白屏
原因:
1)打包后文件引用路径不对,导致找不到文件报错白屏
解决办法:修改一下config
下面的index.js
中bulid
模块导出的路径。因为index.html
里边的内容都是通过script
标签引入的,而你的路径不对,打开肯定是空白的。先看一下默认的路径。
2)由于把路由模式mode设置影响,删除mode或者把mode改成hash就OK了。
3)项目中使用了es6的语法,一些浏览器不支持es6,造成编译错误不能解析而造成白屏
- 安装 npm install --save-dev babel-preset-es2015
- 安装 npm install --save-dev babel-preset-stage-3
- 在项目根目录创建一个.babelrc文件 里面内容 最基本配置是:
{
// 此项指明,转码的规则
"presets": [
// env项是借助插件babel-preset-env,下面这个配置说的是babel对es6,es7,es8进行转码,并且设置amd,commonjs这样的模块化文件,不进行转码
["env", {
"modules": false
}],
// 下面这个是不同阶段出现的es语法,包含不同的转码插件
"stage-2"
],
// 下面这个选项是引用插件来处理代码的转换,transform-runtime用来处理全局函数和优化babel编译
"plugins": ["transform-runtime"],
// 下面指的是在生成的文件中,不产生注释
"comments": false,
// 下面这段是在特定的环境中所执行的转码规则,当环境变量是下面的test就会覆盖上面的设置
"env": {
// test 是提前设置的环境变量,如果没有设置BABEL_ENV则使用NODE_ENV,如果都没有设置默认就是development
"test": {
"presets": ["env", "stage-2"],
// instanbul是一个用来测试转码后代码的工具
"plugins": ["istanbul"]
}
}
}
4)、第四种,如果你的测试说你的项目在 ios 10 出现白屏问题
- 进入build文件夹;
- 找到webpack.prod.conf.js文件;
- 在UglifyPlugin的定义里添加关于mangle的选项,使它变成下面这个样子:
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
},
mangle: {
safari10: true
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
5、使用不支持ES6的方法,比如Swiper,更改
module.exports = {
chainWebpack: config => {
config.rule('js').include.add(/node_modules\/(dom7|swiper)\/.*/)
}
}
加载慢的解决方法:
1)、路由的懒加载
2)、ui框架按需加载(ui里的模块)
3)、gizp压缩
//下载资源
npm i compression-webpack-plugin -D
//vue.config.js配置
const CompressionPlugin = require("compression-webpack-plugin")
module.exports = {
configureWebpack: () => {
if (process.env.NODE_ENV === 'production') {
return {
plugins: [
new CompressionPlugin({
test: /\.js$|\.html$|\.css$|\.jpg$|\.jpeg$|\.png/, // 需要压缩的文件类型
threshold: 10240, // 归档需要进行压缩的文件大小最小值,我这个是10K以上的进行压缩
deleteOriginalAssets: false, // 是否删除原文件
minRatio: 0.8
})
]
}
}
}
}
4、loading
首页加一个loading或许是最原始的方法了,在index.html里加一个loadingcss效果,当页面加载完成消失,友好用户体验感