前端基础整理 | 网络相关(二)

文章首发地址:http://www.brandhuang.com/article/1585139147636html

跨域

在先后端分离的开发模式中,常常发生跨域的问题,前端发送了请求,服务器也作出了响应,可是前端却拿不到这个响应前端

为何服务器作出了正确的响应,前端却拿不到这个响应呢?chrome

由于浏览器都遵循一个同源策略(协议、主机和端口都相同,则同源)。对非同源站点,浏览器会做出一些限制:segmentfault

  • 不能读取和修改对方的 DOM
  • 不读访问对方的 Cookie、IndexDB 和 LocalStorage
  • 限制 XMLHttpRequest 请求。

当浏览器向服务器发起 Ajax 请求时,若是当前的 URL 和目标的 URL不一样源,则为 跨域请求后端

跨域请求的响应会被客户端拦截(注意:响应其实已经被客户端获取到了,只是被拦截了api

处理跨域 | CORS

CORS 是 W3C 的一个标准,全称 跨域资源共享。支持非 ie 以及 ie10 以上。 须要服务器附加特定的响应头

浏览器根据请求方法和请求头的特定字段,将请求分为了简单请求非简单请求。针对这两类不一样的请求进行不一样的处理跨域

简单请求

简单请求知足如下条件:浏览器

  • 请求方法为 GET、POST 或者 HEAD
  • 请求头的取值范围: Accept、Accept-Language、Content-Language、Content-Type(只限于三个值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目标地址,同时加上两个关键字段:

  • Access-Control-Request-Method, 列出 CORS 请求用到哪一个HTTP方法
  • Access-Control-Request-Headers,指定 CORS 请求将要加上什么请求头

预检请求响应以下:

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请求也不会发出去了。

处理跨域 | JSONP

原理:动态建立script标签,它能够经过 src 填上目标地址从而发出 GET 请求,实现跨域请求并拿到响应.

JSONP 与 CORS 比较

CORS相比,JSONP 最大的优点在于兼容性好,IE 低版本不能使用 CORS 但可使用 JSONP,缺点也很明显,请求方法单一,只支持 GET 请求。

处理跨域 | Nginx

服务器进行以下配置:

server {
  listen  80;
  server_name  client.com;
  location /api {
    proxy_pass server.com;
  }
}

处理跨域 | PostMessage

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:短轮询、长轮询、长链接
  • 非 HTTP:Websocket

短轮询(Polling)

基本实现思路:浏览器每隔一段时间定时向服务器发送 HTTP 请求,服务器收到请求后当即进行响应(无论内容是否发生变化)。响应完成后 TCP 链接关闭。

长轮询(Comet)

基本实现思路:当服务器收到客户端发来的请求后,不会直接进行响应,而是先将这个请求挂起,而后判断服务器端数据是否有更新。若是有更新,则进行响应,若是一直没有数据,则到达必定的时间限制(服务器端设置)后关闭链接。

长轮询和短轮询比起来,减小了不少没必要要的http请求次数。可是长轮询的链接一直挂起也会致使资源的浪费。

长链接(SSE)

查看 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

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);
});

CDN

全称 content delivery network,内容分发网络。是一组分布在多个不一样的地理位置的服务器。根据用户的实际位置,从离用户最近的 CDN 服务器为用户提供内容,提升访问速度,提高用户体验。

主要用来解决网络拥堵,提升访问速度,解决因为网络带宽小,用户访问量大,网点分布不均等缘由致使的访问速度慢的问题。

CDN的大体原理:

  1. 用户在浏览器输入要访问的域名;
  2. 对域名进行解析,因为CDN对域名解析过程进行了调整,因此解析函数库通常获得的是该域名对应的CNAME记录,为了获得实际的IP地址,浏览器须要再次对得到的CNAME域名进行解析以获得实际的IP地址;在此过程当中,使用的全局负载均衡DNS解析。如根据地理位置信息解析对应的IP地址,使得用户能就近访问;
  3. 这次解析获得CDN缓存服务器的IP地址,浏览器在获得实际的ip地址以后,向缓存服务器发出访问请求;
  4. 缓存服务器根据浏览器提供的要访问的域名,经过Cache内部专用DNS解析获得此域名的实际IP地址,再由缓存服务器向此实际IP地址提交访问请求;
  5. 缓存服务器从实际IP地址获得内容之后,一方面在本地进行保存,以备之后使用,二方面把获取的数据放回给客户端,完成数据服务过程;
  6. 客户端获得由缓存服务器返回的数据之后显示出来并完成整个浏览的数据请求过程。

本文先整理这么多吧,反正一次也消化不完。

若是喜欢本文但愿能点个赞~

固然能够关注我来获取后续文章

也能够关注我我的博客

还也能够关注我公众号「九零后重庆崽儿」。

brand.jpg

相关文章
相关标签/搜索