文章首发地址:http://www.brandhuang.com/article/1585139147636html
在先后端分离的开发模式中,常常发生跨域的问题,前端发送了请求,服务器也作出了响应,可是前端却拿不到这个响应
。前端
为何服务器作出了正确的响应,前端却拿不到这个响应呢?chrome
由于浏览器都遵循一个同源策略(协议、主机和端口都相同,则同源)
。对非同源站点,浏览器会做出一些限制:segmentfault
当浏览器向服务器发起 Ajax 请求时,若是当前的 URL 和目标的 URL不一样源,则为 跨域请求
。后端
跨域请求的响应会被客户端拦截(注意:响应其实已经被客户端获取到了,只是被拦截了
)api
CORS 是 W3C 的一个标准,全称跨域资源共享
。支持非 ie 以及 ie10 以上。须要服务器附加特定的响应头
。
浏览器根据请求方法和请求头的特定字段,将请求分为了简单请求
和非简单请求
。针对这两类不一样的请求进行不一样的处理跨域
简单请求知足如下条件:浏览器
application/x-www-form-urlencoded、multipart/form-data、text/plain
)请求发出去前,浏览器在请求头中添加 Origin
字段,服务器在响应中添加 Access-Control-Allow-Origin
字段,若是这个字段不在 Origin
字段的范围中,则浏览器拦截响应。所以,Access-Control-Allow-Origin
字段是服务器用来决定浏览器是否拦截这个响应,这是必需的字段。缓存
Access-Control-Allow-Credentials
是一个布尔值,表示是否容许发送 Cookie。浏览器对这个字段默认值设为 false
,若要浏览器请求携带cookie,须要添加这个响应头并设为true, 而且在前端也须要设置withCredentials属性为 true,服务器
let xhr = new XMLHttpRequest(); xhr.withCredentials = true;
除了简单请求以外的请求 (PUT DELETE PATCH等)
发起非简单请求时,会先发起预检请求(OPTIONS)
,同时会加上Origin
源地址和Host
目标地址,同时加上两个关键字段:
预检请求响应以下:
HTTP/1.1 200 OK Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1728000 Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Content-Length: 0
在预检请求的响应返回后,若是请求不知足响应头的条件,则触发XMLHttpRequest的onerror
方法,固然后面真正的CORS请求也不会发出去了。
原理:动态建立script
标签,它能够经过 src 填上目标地址从而发出 GET 请求,实现跨域请求并拿到响应.
和CORS
相比,JSONP
最大的优点在于兼容性好,IE 低版本不能使用 CORS
但可使用 JSONP
,缺点也很明显,请求方法单一,只支持 GET 请求。
服务器进行以下配置:
server { listen 80; server_name client.com; location /api { proxy_pass server.com; } }
MDN文档: window.postMessage
otherWindow.postMessage(message, targetOrigin, [transfer]); window.addEventListener("message", receiveMessage, false); function receiveMessage(event) { // For Chrome, the origin property is in the event.originalEvent // object. // 这里不许确,chrome没有这个属性 // var origin = event.origin || event.originalEvent.origin; var origin = event.origin if (origin !== "http://example.org:8080") return; // ... }
更详细的解释,能够参看神三元大佬的文章:http://www.javashuo.com/article/p-unqnwopd-ep.html
即时通信,一种基于互联网的即时交流消息的业务。。
实现即时通信主要有四种方式:短轮询
、长轮询(comet)
、长链接(SSE)
、WebSocket
。
上述四种可分为两类:
基本实现思路:浏览器每隔一段时间定时向服务器发送 HTTP 请求,服务器收到请求后当即进行响应(无论内容是否发生变化)。响应完成后 TCP 链接关闭。
基本实现思路:当服务器收到客户端发来的请求后,不会直接进行响应,而是先将这个请求挂起,而后判断服务器端数据是否有更新。若是有更新,则进行响应,若是一直没有数据,则到达必定的时间限制(服务器端设置)后关闭链接。
长轮询和短轮询比起来,减小了不少没必要要的http请求次数
。可是长轮询的链接一直挂起
也会致使资源的浪费。
查看 MDN文档
HTML5新增的功能,由客户端发起
与服务器之间建立TCP链接,并维持这个链接,直到客户端或服务器中的任何一方断开。链接建立后,浏览器会周期性地发送消息至服务器询问
。HTTP响应内容有一种特殊的content-type —— text/event-stream
,该响应头标识了响应内容为事件流
,客户端不会关闭链接
,而是等待服务端不断得发送响应结果。
使用:
var source = new EventSource('/XXX'); // 默认的事件 source.addEventListener('message', function (e) { console.log(e.data); }, false); // 用户自定义的事件名 source.addEventListener('my_msg', function (e) { process(e.data); }, false); // 监听链接打开 source.addEventListener('open', function (e) { console.log('open sse'); }, false); // 监听错误 source.addEventListener('error', function (e) { console.log('error'); });
WebSocket是Html5定义的一个新协议,与传统的 HTTP 协议不一样,可实现服务端和客户端双向同时通讯(全双工通讯)
。
首先经过 HTTP 来让客户端和服务端创建链接,链接创建后就再也不使用 HTTP 协议,便可进行数据传递。
const socket = new WebSocket('ws://localhost:8080'); // Connection opened socket.addEventListener('open', function (event) { socket.send('Hello Server!'); }); // Listen for messages socket.addEventListener('message', function (event) { console.log('Message from server ', event.data); });
全称 content delivery network,内容分发网络。是一组分布在多个不一样的地理位置的服务器。根据用户的实际位置,从离用户最近的 CDN 服务器为用户提供内容,提升访问速度,提高用户体验。
主要用来解决网络拥堵,提升访问速度,解决因为网络带宽小,用户访问量大,网点分布不均等缘由致使的访问速度慢的问题。
CDN的大体原理:
获得的是该域名对应的CNAME记
录,为了获得实际的IP地址,浏览器须要再次对得到的CNAME域名进行解析
以获得实际的IP地址;在此过程当中,使用的全局负载均衡DNS解析。如根据地理位置信息解析对应的IP地址,使得用户能就近访问;获得CDN缓存服务器的IP地址
,浏览器在获得实际的ip地址以后,向缓存服务器发出访问请求;获得此域名的实际IP地址
,再由缓存服务器向此实际IP地址提交访问请求;本文先整理这么多吧,反正一次也消化不完。
若是喜欢本文但愿能点个赞~
固然能够关注我来获取后续文章
也能够关注我我的博客
还也能够关注我公众号「九零后重庆崽儿」。