内容导读
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。最大特点就是简单适用,老式浏览器全部支持,服务端改造非常小,缺点是只能发GET请求。两个网页都需要设置相同的document.domain属性,才可以共享 Cookie,获取DOM。大多数情况下,浏览器会智能判断,将重流和重绘只限制到相关的子树上面,最小化所耗费的代价。每个域名的存储上限视浏览器而定,Chrome是2.5MB,Firefox和Opera是5MB,IE是10MB。history对象 back() 移动到上一个访问页面,等同于浏览器的后退键。
缓存
- 关于缓存的好处与优点就不说了,简单说说浏览器的缓存机制。
- 当浏览器向服务器发起请求时,首先会判断是否有缓存,如果没有缓存,则正常向服务器发起请求;
- 如果有缓存,先判断缓存是否过期,如果未过期,直接使用缓存;
- 如果过期,则向服务器发起请求,判断资源是否有更新,如果有更新,则返回新的资源(200);
- 如果资源未更新,则继续使用缓存(304)。
- http报文中与缓存相关的首部字段
- Cache-Control
- Cache-Control可以控制告诉客户端或是服务器如何处理缓存。只有很多,常用的有no-store,no-cache,max-age。
- no-store表示禁用缓存;no-cache表示可以使用缓存,但是每次都必须到服务器验证资源的有效性(无论资源有没有过期);max-age表示缓存的时长,是相对时间,单位为秒。优先级高于Expires
- If-None-Match与ETag
- ETag是资源的唯一标识,优先级高于Last-Modified。
- If-None-Match的值为上次请求资源文件时响应头字段ETag的值,在第二次请求时作为请求头发给服务器,服务端通过 If-None-Match字段来判断在这两次访问期间资源有没有被修改过。如果有修改正常返回资源,状态码200,如果没有修改只返回响应头,状态码304,告知浏览器资源的本地缓存还可用。
- If-Modified-Since与Last-Modified
- Last-Modified标记资源文件在服务器端最后被修改的时间。
- If-Modified-Since的值为上次请求资源文件时响应头字段Last-Modified的值,在第二次请求时作为请求头发给服务器,服务端通过If-Modified-Since字段来判断在这两次访问期间资源有没有被修改过。如果有修改正常返回资源,状态码200,如果没有修改只返回响应头,状态码304,告知浏览器资源的本地缓存还可用。
- Expires
- Expires是用来定义缓存到期时间的字段,值为绝对时间。
- 有一个弊端:它返回的是服务器的时间,但判断的时候用的却是客户端的时间,如果客户端时间与服务器 时间不一致,则导致缓存时间判断出错。
同源策略
- 目的
- 同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
- 定义
- 所谓“同源”指的是协议相同,域名相同,端口相同。
- 限制
- 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)。
- 无法接触非同源网页的 DOM,非同源网页之间无法进行通信。
- 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB。
跨域手段
- CORS
- CORS 是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。CORS 允许任何类型的请求。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。
- WebSocket
- WebSocket 是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
- JSONP
- JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务端改造非常小,缺点是只能发GET请求。
- 实现思路:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
CORS,WebSocket,JSONP 是解决限制1的。
只要跨域,父窗口与子窗口之间就无法获取对方的DOM,无法通信。为了解决这个问题,有如下方法:
- document.domain
- 如果两个网页一级域名相同,只是次级域名不同,浏览器允许通过设置document.domain共享 Cookie。
- 两个网页都需要设置相同的document.domain属性,才可以共享 Cookie,获取DOM。
- loca
- URL有一部分被称为hash,就是#号及其后面的字符,它一般用于浏览器锚点定位,修改它不会产生HTTP请求。
- 父窗口可以把信息,写入子窗口的片段标识符。子窗口通过监听hashchange事件得到通知。从而实现通信。反之一样。
- postmessage
- window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。
- postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即“协议 + 域名 + 端口”。也可以设为*,表示不限制域名,向所有窗口发送。
- 父窗口和子窗口都可以通过postMessage方法向对方发送消息。
- 父窗口和子窗口都可以通过message事件,监听对方的消息。message事件的参数是事件对象event。
- event.source:发送消息的窗口;event.origin: 消息发向的网址;event.data: 消息内容
document.domain,loca,postMessage是为了解决限制2和限制3的
重流与重绘
- 重流
- 简单说就是重新计算网页布局。
- 重绘
- 简单说就是根据新布局重新渲染网页。所以,重流必然导致重绘,重绘不一定需要重流。
- 大多数情况下,浏览器会智能判断,将重流和重绘只限制到相关的子树上面,最小化所耗费的代价。
- 作为开发者,应该尽量设法降低重绘的次数和成本。
浏览器存储
- sessionStorage和localStorage
- 它们除了保存期限的长短不同(sessionStorage保存的数据用于浏览器的一次会话,localStorage保存的数据长期存在),其余完全相同。
- 它们也受同域限制。每个域名的存储上限视浏览器而定,Chrome是2.5MB,Firefox和Opera是5MB,IE是10MB。
- 当储存的数据发生变化时,会触发storage事件。值得特别注意的是,该事件不在导致数据变化的当前页面触发。
- Cookie
- 它的容量很小(4KB),缺乏数据操作接口,并不推荐作为客户端储存。
拦截窗口的判断
主要利用window.open方法,该方法用于新建另一个浏览器窗口,并且返回该窗口对象。如果返回null则打开失败。
var newPop = window.open(url) if(!newPop){ alert('您有默认程序阻止打开新窗口,请关闭后再试') }多窗口操作
window.top: 顶层窗口; window.parent: 父窗口;window.self: 当前窗口。
浏览器还提供一些特殊的窗口名,供open方法、<a>标签、<form>标签等引用。
_top:顶层窗口;_parent:父窗口;_blank:新窗口
下面代码就表示在顶层窗口打开链接。
<a href="; target="_top">Link</a>navigator对象
window对象的navigator属性,指向一个包含浏览器信息的对象。
naviga //返回浏览器的厂商和版本信息,用来识别浏览器 naviga //返回用户的操作系统信息。 naviga //返回一个类似数组的对象,成员是浏览器安装的插件。 naviga //使用的语言,用作国际化。 naviga //返回一个Geolocation对象,包含用户地理位置的信息。Geolocation对象
getCurrentPosition方法,用来获取用户的地理位置。
watchPosition方法可以用来监听用户位置的持续改变,使用方法与getCurrentPosition方法一样。
watchPosition方法返回的标识符,用于供clearWatch方法取消监听。
var geolocation = naviga function geoSuccess(event) { con) //返回获得位置信息的具体时间 con) //一个对象,包含了用户的位置信息 con.latitude) //纬度 con.longitude) //经度 con.accuracy) //精度 con.altitude) //海拔 con.altitudeAccuracy) //海拔精度 con.heading) //以360度表示的方向 con.speed) //每秒的速度 } function geoError(event) { con) //表示错误类型 con) //表示错误信息 } geoloca(geoSuccess, geoError)history对象
- back() 移动到上一个访问页面,等同于浏览器的后退键。
- forward() 移动到下一个访问页面,等同于浏览器的前进键。
- go() 接受一个整数作为参数,移动到该整数指定的页面,比如go(1)相当于forward(),go(-1)相当于back()。go(0)相当于刷新当前页面。
- pushState() 在浏览历史中添加记录,接受三个参数:第一个参数为一个与指定网址相关的状态对象,第二个为新页面的标题,第三个为新的网址,浏览器的地址栏将显示这个网址。
- 不会触发页面刷新,只是导致history对象发生变化,地址栏会有反应。
- replaceState() 在浏览历史中修改记录,参数与pushState保持一致。
- state 返回当前页面的state对象。