同源策略是浏览器一个重要的安全策略,它用于限制一个 origin 的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介
同源的定义是两个 URL 的 协议、域名(子域名 + 主域名)、端口号 都相同,否则就会出现跨域
AJAX 请求不能发送API 访问: DOM 无法获得Cookie LocalStorage 和 IndexDB 无法读取一般常说的跨域指网络跨域
CORS (跨源资源共享) 是 HTTP 的一部分,它允许浏览器向跨源服务器发出 XMLHttpRequest 请求,从而解决了 AJAX 只能同源使用的限制。
CORS需要浏览器和服务器同时支持,目前所有浏览器均已支持,只需服务器配置即可使用
浏览器将 CORS 请求分成两类: 简单请求和非简单请求
日常开发只会关注前两点
HEADGETPOSTAcceptAccept-LanguageContent-LanguageContent-Type 仅限以下三种
application/x-www-form-urlencodedmultipart/form-datatext/plainXMLHttpRequestUpload 对象均没有注册任何事件监听器(使用 XMLHttpRequest.upload 属性访问XMLHttpRequestUpload 对象)ReadableStream 对象CORS 请求并在请求头信息之中增加一个 Origin 字段(用来说明本次请求来自哪个源(协议 + 域名 + 端口))Origin 字段决定是否同意这次请求CORS 相关的字段(以Access-Control-开头)CORS 相关的字段,浏览器会抛出异常Access-Control-Allow-Origin: 只能是 *(接受任意域名的请求)或者是请求时 Origin 字段的值Access-Control-Allow-Credentials(可选): 是一个布尔值,表示是否允许发送 CookieAccess-Control-Expose-Headers(可选): CORS 请求时 XMLHttpRequest 对象的 getResponseHeader() 方法只能拿到 6 个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段就必须在 Access-Control-Expose-Headers 里面指定CORS 请求默认不发送 Cookie,如果需要发送需要满足如下条件
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin 字段不能为 *AJAX 请求的配置项需设置 withCredentials = true非简单请求是那种对服务器有特殊要求的请求,如请求方法是 PUT 或 DELETE,或者 Content-Type 字段的类型是 application/json。 非简单请求会在正式通信之前增加一次 HTTP 查询请求,称为预检请求,用于获取服务器是否允许该实际请求,同时避免跨域请求对服务器的用户数据产生预期之外的影响
预检请求用的请求方法是 OPTIONS 表示这个请求是用来询问的
Origin: 表示本次请求来自哪个源Access-Control-Request-Method: 用于列出浏览器的 CORS 请求会用到哪些 HTTP 方法Access-Control-Request-Headers(可选): 指定浏览器 CORS 请求会额外发送的头信息字段Access-Control-Allow-OriginAccess-Control-Allow-Credentials(可选)Access-Control-Allow-Methods: 表示服务器支持的所有跨域请求的方法(为了避免多次预检请求)Access-Control-Allow-Headers: 表示服务器支持的所有头信息字段,不限于浏览器在预检中请求的字段Access-Control-Max-Age(可选): 用来指定本次预检请求的有效期单位为秒,在有效期内将不发出另一条预检请求一旦服务器通过了预检请求,以后每次浏览器正常的 CORS 请求,就都跟简单请求一样会有一个 Origin 头信息字段。服务器的回应也都会有一个 Access-Control-Allow-Origin 头信息字段
JSONP 是利用 <script> 标签没有跨域限制的漏洞,当前源可以得到从其他来源动态产生的 JSON 数据
JSONP 请求过程流程
script 标签,其 src 指向接口地址并拼接好参数和回调函数名JavaScript 脚本 )JavaScript 脚本代码(调用定义好的回调函数)并删除刚创建的 script 标签GET 请求XSS 攻击Expires 是服务器告诉浏览器的缓存过期时间(值为 GMT 时间,即格林尼治时间)
HTTP1.0 的产物max-age=xxx(xxx 是 秒)Cache-Control 用于控制缓存的行为
HTTP1.1 的产物public:允许被客户端和代理服务器缓存private:只允许被客户端缓存(默认值)no-cache:允许被客户端和代理服务器缓存,但在使用缓存时需要经过协商缓存来验证决定no-store:所有内容都不会被缓存,即不使用强制缓存也不使用协商缓存每次请求都会下载完整的资源maxage=xxx:设置客户端和代理服务器的缓存时间,表示缓存内容将在 xxx 秒后失效s-maxage=xxx:设置代理服务器的缓存时间(优先级比 max-age 高)no-cache 名字存在误导,其并不是不缓存数据,只是在使用缓存时需要经过协商缓存来验证决定 max-age=0 和 no-cache 效果一致
JS 和图片文件会存入内存200(from memory cache)I/O 操作memory cache 慢css200(from disk cache)HTTPS 下可用、存在兼容问题200(from service worker)Last-Modified 和 If-Modified-SinceLast-Modified 表示资源的最后修改时间,值为 GMT 格式时间字符串,精确到秒
Last-ModifiedIf-Modified-Since 值为上次请求返回的 Last-ModifiedIf-Modified-Since 和该资源在服务器的最后被修改时间做对比
If-Modified-Since 重新返回资源文件,状态码为 200If-Modified-Since 资源无更新继续使用缓存文件,状态码为 304ETag 是服务器通过算法对资源内容计算出的一个唯一标识(文件 hash)其有强弱之分
Etag
ETag: "<etag_value>"Etag(使用 W/ 标识)
ETag: W/"<etag_value>"ETagIf-None-Match 值为上次请求返回的 ETagETag 和服务器重新生成的 ETag 进行对比
Etag 优于 Last-ModifiedEtag < Last-Modified 每次生成 ETag 都需要进行读写操作,而 Last-Modified 只需要读取操作Etag| 强缓存 | 协商缓存 |
|---|---|
| 不常变化的文件带 hash 值的 css js 图片 | 频繁变动的文件html 文件 |
disk cache(磁盘缓存)中是否有匹配,有则使用缓存,没有则发送网络请求tab 标签并没有关闭,因此 memory cache (内存缓存)是可用的,会被优先使用,其次使用 disk cache(磁盘缓存)Cache-control: no-cache (为了兼容还带了 Pragma: no-cache)服务器直接返回 200 和最新内容。Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能,Cookie 在存储时是以键值对的形式存在的
Cookie 主要用于以下三个方面:
Cookie 的本职工作并非本地存储,而是“维持状态”,因当时并没有其它合适的存储办法而作为唯一的存储手段,所以会用其进行本地存储
http response header 中的 set-cookieJavaScript 中使用 document.cookie 进行读写Cookie 最大只能有 4KB 同时大多数浏览器对一个站点的 Cookie 个数也是有限制的Cookie 从而带来不必要的开销和安全问题Web Storage是 HTML5 专门为浏览器存储而提供的数据存储机制,其大小限制为 5MB ~ 10MB (去查看当前浏览器下 Web Storage 的容量限制),数据仅保存在客户端不与服务器进行通信
Web Storage 提供了两种机制供我们使用
Local Storage(本地存储)Session Storage(会话存储)SessionStorage 数据SessionStorage 数据是独立的,不会相互影响(类似深拷贝)以
localStorage为例
Cookie: 可以设置失效时间(默认是关闭浏览器后失效)localStorage: 除非被手动清除否则将会永久保存sessionStorage: 仅在当前浏览器的标签页下有效,关闭标签或窗口后就会被清除Cookie: 4KBlocalStorage 和 sessionStorage: 5MB ~ 10MBCookie: 每次都会携带在 HTTP 请求头中localStorage 和 sessionStorage: 仅在客户储保存不会与服务器通信IndexedDB 是一个运行在浏览器上的非关系型数据库,用于在客户端存储大量结构化数据
250MB 甚至没有上限)ArrayBuffer 和 Blob)打开/创建一个 IndexedDB 数据库,并指定数据库的版本号 (版本号只能为整数)
创建一个对象仓库(类似于数据库中的表)
添加数据
获取数据
修改数据
删除数据
name:value 的简单语法的客户端数据存储垫片,基于 IndexedDB 实现,并在不持支 IndexedDB 的浏览器中自动回退到 WebSQL 和 localStorageIndexedDB 的封装,通过提供更友好和简单语法进行快速的编码开发IndexedDB 的封装,通过提供更友好和简单语法进行快速的编码开发