Open pomelovico opened 6 years ago
[TOC]
跨域资源共享
浏览器发起异步请求时,如果是跨域操作,会自动携带相应的请求头信息(Origin),所以关键在于服务端实现CORS接口;
浏览器在请求头中携带"Origin"字段
服务器设置:
"Access-Control-Allow-Origin:*"/*允许跨域的域名*/ "Access-Control-Allow-Credentials:true"/*设置只能是true,表示允许浏览器发送cookie,此时Origin必须指定对应的域*/ "Access-Control-Espose-Headers:"/*可以拿到额外的请求头*/
Ajax设置如下可以发送Cookie,默认的异步跨域请求是不会携带cookie
"withCredentials:true"
且只会发送该域下的cookie,其他域的cookie不会发送
浏览器发送预检请求(OPTIONS),用以了解服务端允许使用哪些HTTP动词,请求头等
待服务器允许后才会发送真正的请求
JSONP是利用了<script>标签加载资源不受同源策略影响来实现的,只支持GET请求,原理就是src请求得到的数据会被JavaScript直译器执行,所以服务端要返回类似callback(data)这种数据
<script>
callback(data)
回流(reflow):render树的一部分或者全部因为大小边距变化而需要重建的过程叫做回流
重绘(repaint):颜色背景等不引起页面布局变化,仅需要重新渲染的过程。
引起回流的操作:
display:none隐藏了元素,元素不显示,不占据空间,改变了DOM结构,所以会产生回流以及重绘
display:none
visibility:hidden使元素不可见,但是保留了元素的空间,没有改变DOM结构,所以只产生了重绘
visibility:hidden
https://kb.cnblogs.com/page/169820/ https://www.cnblogs.com/dll-ft/p/5810639.html
websocket是HTML5中提出的一个协议,HTML5提供了一整套支持websocket的API供使用。
相对于无状态的HTTP协议来说,websocket实现了持久化的链接,websocket借助HTTP完成了部分的握手链接,浏览器会向服务端发起连接请求告诉服务端当前客户端需要一个支持socket连接的服务器来提供服务。连接建立后,客户端不需要定时向服务端发起轮询请求,服务端可以直接推送数据到客户端。
相比于传统的长轮询,ajax轮询来说,websocket减少了每次发起请求时建立连接的资源消耗,减少了服务端的压力。
另外,HTTP中的keep-alive机制是将多个请求合并成一个(一个请求结束后不会关闭请求,下一个请求会继续使用该次建立好的连接),并不是长轮询。
Cookie存储数据容量大小有限制,一般为4KB,保存当前域下的用户信息,可以设置过期时间,会随着HTTP请求,放在请求头中发送到服务端,保存的形式是一个字符串。需要自行实现一套cookie操作的API
LocalStorage是HTML5种提供的功能,提供了一系列的API函数对存储的数据进行操作,可以在本地存储大容量数据,Chrome的容量大小8MB,没有过期时间,永久的存储在浏览器中,关闭浏览器后也仍然保留,不随HTTP请求发送。
SessionStorage与LocalStorage使用方式类似,但其生命周期在浏览器关闭之前,浏览器关闭之后SessionStorage将会丢失。从某页面中打开的其他页面(链接跳转,window.open,local.herf)可以访问到这个页面的sessionStorage,刷新页面不会丢失SessionStorage。
在非IE浏览器中,事件的触发经过三个阶段:事件捕获,事件对象,事件冒泡。IE8及一下环境中没有事件捕获阶段。
所谓事件代理指的是,利用事件捕获或者事件冒泡阶段,将一些经常动态增减的元素的事件绑定在父元素上面,在父元素上绑定的事件触发时,通过事件回调函数中给出的事件对象event.target来判断是否为我们真正需要绑定事件的子元素,从而做出相应的处理。这种方式可以减少内存泄漏的风险,因为为元素频繁的绑定事件会耗费大量的内存。
event.target
https://www.cnblogs.com/diver-blogs/p/5649270.html
https://www.cnblogs.com/dfyg-xiaoxiao/articles/6213063.html
跨站脚本攻击(Cross Site Scripting),缩写为XSS
恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
避免方法:对用户提交的内容进行HTML Entity编码转换,或者过滤一些script,iframe(广告多用)节点
CSRF跨站点请求伪造(Cross—Site Request Forgery
冒充用户在站内的正常操作,让用户在本机(拥有cookie的浏览器)发起用户不知情的请求。
CSRF攻击者并不能获取cookie,解析服务器返回的内容(同源策略限制),能做的就是向攻击的服务器发起请求(以受害者的身份)以更改数据,并不能窃取数据
攻击方式:
img.src
src
防御策略:
验证HTTP头部的referer字段,该字段表明了请求的来源地址(但是该referer字段依赖于浏览器的实现,相当于把安全行保护交给了第三方)
token(令牌)验证 , 在所有的请求中加入token数据,与服务端session中保存的token做验证对比
HTTP 头中自定义属性并验证,通过xmlHttpRequest这个类实例,统一在提交的请求的头部加上验证信息
当表单提交时,用JavaScript在本域添加一个,临时的Cookie字段,并将过期时间设为1秒之后在提交,服务端校验有这个字段即放行,没有则认为是CSRF攻击。(Cookie只能在父域和子域中设置,由于同源策略的限制,攻击者无法设置该cookie)
json数据返回,可以在返回的json数据前面添加while(1)
while(1)
http://blog.csdn.net/stpeace/article/details/53512283 http://www.vuln.cn/7134
彻底弄懂HTTP缓存机制及原理
三大缓存方式:
Expires值是一个绝对时间,告诉浏览器该文档在该时间之前有效,但是由于浏览器时间和服务器时间可能不一致,所以会导致缓存永久失效或永久有效的问题,不推荐使用,在同时存在Expires和Cache-Control的情况下,后者优先。
Expires
Cache-Control
Cache-Control在响应首部和请求首部都会出现。在响应首部出现则说明服务器再告诉浏览器该文档的缓存相对时间。若是出现在请求首部,则会被浏览器处理该请求时截获,浏览器根据Cache-Control的值来判断是否读取本地缓存。Cache-Control其有以下几种值:
no-cache
no-store
max-age
Pragma:no-cache也可以用户缓存控制,仅用于HTTP请求,兼容HTTP/1.0
Pragma:no-cache
当缓存对已缓存的文档进行再验证的时候,请求头部就会包含一个If-Modified-Since字段,该字段就是该来自缓存文档响应头部的Last-Modified值,是有服务器给出的文档最后修改的日期,若此期间文档做了修改,则服务器会发送新的文档,否则返回304 Not Modified响应,但不会返回文档主体(减少了传输数据量)
If-Modified-Since
Last-Modified
304 Not Modified
但是这个时间是秒级的,在秒级以内的时间内对文档做了修改后,则不能正确的判断文档是否修改过
服务器可以根据HTTP请求中的If-None-Match字段来比较文档是否有做过修改,该字段携带的是缓存文档响应首部中的Etag字段的值,作为该文档的版本标识符,Etag可以是任意的文档的序列号、版本号、或者文档内容校验等信息。
If-None-Match
Etag
如果服务器将请求首部的If-None-Match字段与文档的Etag匹配成功,说明文档没有做修改,会直接返回304 Not Modified响应,验证成功。否则会返回200响应,并携带一个新的Etag
HTTP2.0是基于谷歌提出的SPDY协议改进提出的,旨在解决HTTP1.1的性能问题
二进制分帧 HTTP2.0中数据流以消息的形式形式发送,而消息由一个或者多个帧组成,帧包含帧首部,可以当作标识,所以帧可以乱序发送,然后根据帧的标识重新组装
多路复用 HTTP1.x中,并发多个请求需要使用多个TCP连接,而浏览器对单域名还有并发请求数的限制。在HTTp2.0中,基于二进制分帧的传输方式可以实现:
流优先级 HTTP2.0中的请求带有一个优先级的值,利用优先级标识,浏览器与客户端都可以根据优先级采取不同的策略来发送消息
服务器推送(Server Push,预测推送)
头部压缩(避免重复发送冗余信息) HTTP1.x中每次通信都会携带一组通用的头部,如资源,浏览器属性,cookie等,采用的是纯文本协议发送,增加了请求负担。在HTTP2.0中,将会压缩这些头部,客户端可服务端会使用首部表的键来跟踪发送过的值,然后不会通过每次请求发送这些值
http://www.alloyteam.com/2015/03/http2-0-di-qi-miao-ri-chang/
php可以通过header()方法设置不同的状态码和状态短语,如:
header()
<?php header('HTTP/1.1 401 Unauthorized'); header('HTTP/1.1 403 Forbidden'); header('HTTP/1.1 404 Not Found');
串行连接
并行连接 指浏览器同时开启多个HTTP请求,这些请求之间互相独立,因此可能会耗费更多的开销在连接建立以及内存分配上
持久连接
Connection
keep-alive
Keep-alive
timeout
max
Connection:keep-alive
Web Worker实现了在浏览器后台线程中运行javascript脚本的能力,在该后台线程中运行脚本不会阻塞主线程,所以可以把计算量大或者费时的操作放到worker线程中运行,worker与主线程之间通过消息传递的方式进行双向通信
Web Worker
API:
onmessage
postMessage
onerror
terminate
close()
两类worker:
Worker
SharedWorker
subworker:在worker内还可以创建新的worker,使用importScript()方法引入,该方法是同步的
importScript()
worker线程中可使用大多数JavaScript特性如:
Navigator
XMLHttpRequest
Array
Object
Date
Math
String
setTimeout
setInterval
不能访问window下的属性,也不能访问DOM
一个专用worker仅仅能被首次生成它的脚本使用,而共享worker可以同时被多个脚本使用。 workers和主线程间的数据传递通过这样的消息机制进行——双方都使用postMessage()方法发送各自的消息,使用onmessage事件处理函数来响应消息(消息被包含在Message事件的data属性中)。这个过程中数据并不是被共享而是被复制。
一个专用worker仅仅能被首次生成它的脚本使用,而共享worker可以同时被多个脚本使用。
workers和主线程间的数据传递通过这样的消息机制进行——双方都使用postMessage()方法发送各自的消息,使用onmessage事件处理函数来响应消息(消息被包含在Message事件的data属性中)。这个过程中数据并不是被共享而是被复制。
[TOC]
CORS
跨域资源共享
浏览器发起异步请求时,如果是跨域操作,会自动携带相应的请求头信息(Origin),所以关键在于服务端实现CORS接口;
浏览器在请求头中携带"Origin"字段
服务器设置:
Ajax设置如下可以发送Cookie,默认的异步跨域请求是不会携带cookie
且只会发送该域下的cookie,其他域的cookie不会发送
浏览器发送预检请求(OPTIONS),用以了解服务端允许使用哪些HTTP动词,请求头等
待服务器允许后才会发送真正的请求
JSONP是利用了
<script>
标签加载资源不受同源策略影响来实现的,只支持GET请求,原理就是src请求得到的数据会被JavaScript直译器执行,所以服务端要返回类似callback(data)
这种数据浏览器的重绘与重排
回流(reflow):render树的一部分或者全部因为大小边距变化而需要重建的过程叫做回流
重绘(repaint):颜色背景等不引起页面布局变化,仅需要重新渲染的过程。
引起回流的操作:
display:none
隐藏了元素,元素不显示,不占据空间,改变了DOM结构,所以会产生回流以及重绘visibility:hidden
使元素不可见,但是保留了元素的空间,没有改变DOM结构,所以只产生了重绘websocket,长轮询和短轮询
websocket是HTML5中提出的一个协议,HTML5提供了一整套支持websocket的API供使用。
相对于无状态的HTTP协议来说,websocket实现了持久化的链接,websocket借助HTTP完成了部分的握手链接,浏览器会向服务端发起连接请求告诉服务端当前客户端需要一个支持socket连接的服务器来提供服务。连接建立后,客户端不需要定时向服务端发起轮询请求,服务端可以直接推送数据到客户端。
相比于传统的长轮询,ajax轮询来说,websocket减少了每次发起请求时建立连接的资源消耗,减少了服务端的压力。
另外,HTTP中的keep-alive机制是将多个请求合并成一个(一个请求结束后不会关闭请求,下一个请求会继续使用该次建立好的连接),并不是长轮询。
Cookie,LocalStorage与SessionStorage的区别
Cookie存储数据容量大小有限制,一般为4KB,保存当前域下的用户信息,可以设置过期时间,会随着HTTP请求,放在请求头中发送到服务端,保存的形式是一个字符串。需要自行实现一套cookie操作的API
LocalStorage是HTML5种提供的功能,提供了一系列的API函数对存储的数据进行操作,可以在本地存储大容量数据,Chrome的容量大小8MB,没有过期时间,永久的存储在浏览器中,关闭浏览器后也仍然保留,不随HTTP请求发送。
SessionStorage与LocalStorage使用方式类似,但其生命周期在浏览器关闭之前,浏览器关闭之后SessionStorage将会丢失。从某页面中打开的其他页面(链接跳转,window.open,local.herf)可以访问到这个页面的sessionStorage,刷新页面不会丢失SessionStorage。
浏览器事件代理的原理
在非IE浏览器中,事件的触发经过三个阶段:事件捕获,事件对象,事件冒泡。IE8及一下环境中没有事件捕获阶段。
所谓事件代理指的是,利用事件捕获或者事件冒泡阶段,将一些经常动态增减的元素的事件绑定在父元素上面,在父元素上绑定的事件触发时,通过事件回调函数中给出的事件对象
event.target
来判断是否为我们真正需要绑定事件的子元素,从而做出相应的处理。这种方式可以减少内存泄漏的风险,因为为元素频繁的绑定事件会耗费大量的内存。https://www.cnblogs.com/diver-blogs/p/5649270.html
https://www.cnblogs.com/dfyg-xiaoxiao/articles/6213063.html
XSS,CSRF,避免方法
跨站脚本攻击(Cross Site Scripting),缩写为XSS
恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
避免方法:对用户提交的内容进行HTML Entity编码转换,或者过滤一些script,iframe(广告多用)节点
CSRF跨站点请求伪造(Cross—Site Request Forgery
冒充用户在站内的正常操作,让用户在本机(拥有cookie的浏览器)发起用户不知情的请求。
CSRF攻击者并不能获取cookie,解析服务器返回的内容(同源策略限制),能做的就是向攻击的服务器发起请求(以受害者的身份)以更改数据,并不能窃取数据
攻击方式:
img.src
以及script的src
属性,都可以发起跨域的get请求,且可以携带当前域下的cookie到服务器方防御策略:
验证HTTP头部的referer字段,该字段表明了请求的来源地址(但是该referer字段依赖于浏览器的实现,相当于把安全行保护交给了第三方)
token(令牌)验证 , 在所有的请求中加入token数据,与服务端session中保存的token做验证对比
HTTP 头中自定义属性并验证,通过xmlHttpRequest这个类实例,统一在提交的请求的头部加上验证信息
当表单提交时,用JavaScript在本域添加一个,临时的Cookie字段,并将过期时间设为1秒之后在提交,服务端校验有这个字段即放行,没有则认为是CSRF攻击。(Cookie只能在父域和子域中设置,由于同源策略的限制,攻击者无法设置该cookie)
json数据返回,可以在返回的json数据前面添加
while(1)
HTTP缓存机制
彻底弄懂HTTP缓存机制及原理
三大缓存方式:
Cache-Control & Expires
Expires
值是一个绝对时间,告诉浏览器该文档在该时间之前有效,但是由于浏览器时间和服务器时间可能不一致,所以会导致缓存永久失效或永久有效的问题,不推荐使用,在同时存在Expires
和Cache-Control
的情况下,后者优先。Cache-Control
在响应首部和请求首部都会出现。在响应首部出现则说明服务器再告诉浏览器该文档的缓存相对时间。若是出现在请求首部,则会被浏览器处理该请求时截获,浏览器根据Cache-Control
的值来判断是否读取本地缓存。Cache-Control
其有以下几种值:no-cache
,文档会被缓存,但是要求浏览器不能直接读本地缓存,需要跟服务器验证(Etag,If-Modified-Since...)之后才能使用no-store
,会禁止缓存对响应进行复制,浏览器不会缓存该文件max-age
,从服务器将文档传来之时开始的一段时间内,该文档都是有效的,若设置为0则表示最大使用时期为0,每次访问都需要刷新Pragma:no-cache
也可以用户缓存控制,仅用于HTTP请求,兼容HTTP/1.0Last-Modified & If-Modified-Since:< cached last-modified date>
当缓存对已缓存的文档进行再验证的时候,请求头部就会包含一个
If-Modified-Since
字段,该字段就是该来自缓存文档响应头部的Last-Modified
值,是有服务器给出的文档最后修改的日期,若此期间文档做了修改,则服务器会发送新的文档,否则返回304 Not Modified
响应,但不会返回文档主体(减少了传输数据量)但是这个时间是秒级的,在秒级以内的时间内对文档做了修改后,则不能正确的判断文档是否修改过
Etag & If-None-Match:
服务器可以根据HTTP请求中的
If-None-Match
字段来比较文档是否有做过修改,该字段携带的是缓存文档响应首部中的Etag
字段的值,作为该文档的版本标识符,Etag
可以是任意的文档的序列号、版本号、或者文档内容校验等信息。如果服务器将请求首部的
If-None-Match
字段与文档的Etag匹配成功,说明文档没有做修改,会直接返回304 Not Modified
响应,验证成功。否则会返回200响应,并携带一个新的Etag
Apache开启HTTP缓存
怎么解决跨域问题,有哪些方法
HTTP 和 HTTPS 有何差异? 听说过 SPDY 么?
HTTP2.0
HTTP2.0是基于谷歌提出的SPDY协议改进提出的,旨在解决HTTP1.1的性能问题
二进制分帧 HTTP2.0中数据流以消息的形式形式发送,而消息由一个或者多个帧组成,帧包含帧首部,可以当作标识,所以帧可以乱序发送,然后根据帧的标识重新组装
多路复用 HTTP1.x中,并发多个请求需要使用多个TCP连接,而浏览器对单域名还有并发请求数的限制。在HTTp2.0中,基于二进制分帧的传输方式可以实现:
流优先级 HTTP2.0中的请求带有一个优先级的值,利用优先级标识,浏览器与客户端都可以根据优先级采取不同的策略来发送消息
服务器推送(Server Push,预测推送)
头部压缩(避免重复发送冗余信息) HTTP1.x中每次通信都会携带一组通用的头部,如资源,浏览器属性,cookie等,采用的是纯文本协议发送,增加了请求负担。在HTTP2.0中,将会压缩这些头部,客户端可服务端会使用首部表的键来跟踪发送过的值,然后不会通过每次请求发送这些值
HTTP状态码
php可以通过
header()
方法设置不同的状态码和状态短语,如:TCP/IP 握手连接与挥手断开连接
DDos攻击
HTTP连接
串行连接
并行连接 指浏览器同时开启多个HTTP请求,这些请求之间互相独立,因此可能会耗费更多的开销在连接建立以及内存分配上
持久连接
Connection
字段指定为keep-alive
告诉服务端该条请求为持久连接,数据传送完之后,不要关闭,以利于后面的请求继续使用该条建立好的连接,同样,服务端也需要在响应首部中指定Connection
字段为keep-alive
,这样客户端才确定服务端支持持久连接的Keep-alive
字段可以指定timeout
以及max
信息,告知客户端服务器大概可以保持多长时间的连接(timeout),以及还可以处理的最多事务数量(max)keep-alive
不是默认开启的,需要客户端主动请求开启,且Connection:keep-alive
需要在每条请求中发送,如果服务器在某条请求中没有收到该字段,则会立即关闭该连接keep-alive
会导致哑代理问题:代理服务器原封不动的转发客户端和服务端之间的数据包,导致服务器和客户端都以为要保持连接,然而代理本身并不了解持久连接,于是一一直等待服务器关闭连接,而客户端仍然用同一条连接向代理发送其他请求,代理会认为同一个连接上不应该有其他的请求,于是不处理,导致客户端也挂起Web Worker
Web Worker
实现了在浏览器后台线程中运行javascript脚本的能力,在该后台线程中运行脚本不会阻塞主线程,所以可以把计算量大或者费时的操作放到worker线程中运行,worker与主线程之间通过消息传递的方式进行双向通信API:
onmessage
:消息事件监听函数postMessage
:向worker线程或者主线程发送消息onerror
:错误事件监听函数terminate
:终止一个worker,worker线程会被立即杀死,不会有任何机会让它完成自己的操作或清理工作,在worker线程里可以直接调用close()
方法来结束自身两类worker:
Worker
SharedWorker
subworker:在worker内还可以创建新的worker,使用
importScript()
方法引入,该方法是同步的worker线程中可使用大多数JavaScript特性如:
Navigator
XMLHttpRequest
Array
,Object
,Date
,Math
,String
setTimeout
,setInterval
不能访问window下的属性,也不能访问DOM