前端要负责和后台(服务器)进行交互,其必然得经过网络,所以懂点网络知识有很大的帮助。
同源策略和跨域
目的:同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
浏览器只对XHR(XMLHttpRequest)请求有同源请求限制,同源就是协议、域名和端口号一致, 不同源的客户端脚本在没有明确授权的情况下,不能读写对方XHR资源,反之不同源脚本读取对方XHR资源就是跨域。
举例来说,www.vivo.com/dir/page.ht…
www.vivo.com/dir2/other.…
vivo.com/dir/other.h…
v1.www.vivo.com/dir/other.h…
www.vivo.com:81/dir/other.h…
www.vivo.com/dir/page.ht…
如果非同源会怎样
三种行为受到限制。
(1) 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB。
(2) 无法接触非同源网页的 DOM。
(3) 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)。
跨域的解决方案
jsonp:JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务端改造非常小。
它的基本思想是,网页通过添加一个<script>元素,向服务器请求 JSON 数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。只支持GET,不支持POST请求,不安全XSS
postMessage:HTML5 为了解决这个问题,引入了一个全新的API:跨文档通信 API(Cross-document messaging)。存在兼容性问题。具体参看 developer.mozilla.org/zh-CN/docs/…
document.domain:仅限于同一域名下的子域
websocket:需要后台配合修改协议,不兼容,需要使用socket.io
WebSocket 是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
proxy:使用代理去避开跨域请求,需要修改nginx、apache等的配置(浏览器请求同源服务器,再由后者请求外部服务)
server {
listen ;
server_name your.domain.name;
location / {
# 把跟路径下的请求转发给前端工具链(如gulp)打开的开发服务器
# 如果是产品环境,则使用root等指令配置为静态文件服务器
proxy_pass http://localhost:5000/;
}
location /api/ {
# 把 /api 路径下的请求转发给真正的后端服务器
proxy_pass http://localhost:8080/service/;
# 把host头传过去,后端服务程序将收到your.domain.name, 否则收到的是localhost:
proxy_set_header Host $http_host;
# 把cookie中的path部分从/api替换成/service
proxy_cookie_path /api /service;
# 把cookie的path部分从localhost:8080替换成your.domain.name
proxy_cookie_domain localhost: your.domain.name
}
}
可能会觉得开发中无感知其实是目前脚手架中引入了webpack-dev-server插件
module.exports = {
dev: {
// webpack编译输出的二级文件夹
assetsSubDirectory: 'static',
assetsPublicPath: '/', // 资源的根目录
// 开发服务器配置
host: ip.address(), // ip地址。默认寻找本机ip
port: vivoConf.devPort, // 开发端口号,当端口号被占用时,主动递增寻找可用的端口号
autoOpenBrowser: true, // 服务启动时,是否自动打开浏览器
errorOverlay: true, // 当出现编译器错误或警告时,在浏览器中显示全屏叠加
notifyOnErrors: true, // 出现错误时,notifier调用操作系统的提示框
poll: false, // 是否开启轮询监控代码发生更改 https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// 设置true,项目在启动的时,会自动lint代码
// 错误和警告将被显示在控制台
useEslint: true,
// 如果为true,在浏览器中
// eslint错误和警告也会显示在错误覆盖
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'source-map',
// 是否通过给文件名后加哈希查询值来避免生成的 source map 被缓存。
// 关掉这一选项有益于 source map 调试。
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: false,
cssSourceMap: false,
// 请求代理表,在这里可以配置特定的请求代理到对应的API接口
// 例如将'/api/xxx'代理到'www.example.com/api/xxx'
proxyTable: vivoConf.proxyTable
},
"proxyTable": {
"/usrprd/v5/security/verify/simplePwd/**": {
"target": "https://usrsys.vivo.com.cn/",
"changeOrigin": true,
"secure": false
},
"/usrprd/v5/security/simplePwd/**": {
"target": "https://usrsys.vivo.com.cn/",
"changeOrigin": true,
"secure": false
},
"/usrprd/v5/findpwd/**": {
"target": "https://usrsys.vivo.com.cn/",
"changeOrigin": true,
"secure": false
},
"/usrprd/v5/basic/**": {
"target": "https://passport.vivo.com.cn/",
"changeOrigin": true,
"secure": false
},
"/pcenter/configPwdBySMS/**": {
"target": "https://passport.vivo.com.cn/",
"changeOrigin": true,
"secure": false
},
CORS:CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)跨域资源共享 CORS 详解。看名字就知道这是处理跨域问题的标准做法。 什么要求使用CORS?
1.以跨站点方式调用XMLHttpRequest或获取 API。
2.Web字体(用于@font-faceCSS中的跨域字体使用),以便服务器可以部署TrueType字体,这些字体只能被允许这样做的网站跨站点加载和使用。www.w3.org/TR/css-font…
3.WebGL textures. developer.mozilla.org/en-US/docs/…
4.Images/video frames drawn to a canvas using drawImage().(使用drawImage()绘制到画布的Images/video)
CORS的工作原理是添加新的HTTP Headers,允许服务器描述允许使用Web浏览器读取该信息的起源集 因此可以认为实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
CORS有两种请求,简单请求和非简单请求(通俗叫法 规范中并没有这么叫fetch.spec.whatwg.org/)也可以理解为不会触发… 和 会触发预检的请求
即所谓的“简单请求” - 满足以下所有条件的请求:
唯一允许的方法是: ·GET ·HEAD ·POST 除了由用户代理自动设置的标头(例如,Connection,User-Agent,或任何与所述抓取规格为“禁止的标题名称”定义名称其它标题的),其允许被手动设置仅标头是那些其中Fetch规范定义为“CORS-safelisted request-header”,它们是: ·Accept ·Accept-Language ·Content-Language ·Content-Type (但请注意以下附加要求) ·DPR ·Save-Data ·Viewport-Width ·Width Content-Type标头唯一允许的值是: ·application/x-www-form-urlencoded ·multipart/form-data ·text/plain
ReadableStream请求中未使用任何对象(这个是实验属性)
非简单请求这里不介绍了
具体参考: developer.mozilla.org/en-US/docs/…
需要后台配合进行相关的设置 developer.mozilla.org/en-US/docs/…
代理和网关
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端'中间人'的角色,接收客户端发送的请求不改变请求的URI并转发给服务器,同时也接收服务器返回的相应并转发客户端 缓存代理:代理转发响应时会预先将资源缓存在代理服务器上当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回 透明代理:转发请求或响应时,不对报文做任何加工的代理类型 网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理,其工作机制和代理类似,而网关能使通信线路上的服务器提供非HTTP协议的服务。
反向代理
大家都有过这样的经历,拨打10086客服电话,可能一个地区的10086客服有几个或者几十个,你永远都不需要关心在电话那头的是哪一个,叫什么,男的,还是女的,漂亮的还是帅气的,你都不关心,你关心的是你的问题能不能得到专业的解答,你只需要拨通了10086的总机号码,电话那头总会有人会回答你,只是有时慢有时快而已。那么这里的10086总机号码就是我们说的反向代理。客户不知道真正提供服务人的是谁。 反向代理隐藏了真实的服务端,当我们请求 www.baidu.com 的时候,就像拨打10086一样,背后可能有成千上万台服务器为我们服务,但具体是哪一台,你不知道,也不需要知道,你只需要知道反向代理服务器是谁就好了,www.baidu.com 就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到真实的服务器那里去。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。
负载均衡和动静分离
负载均衡是反向代理的一种,后端多台服务器,nginx根据权重、压力、带宽的分配服务器,避免等待和拥塞 动静分离是反向代理的一种,后端服务器分为动态资源服务器和静态资源服务器,nginx会根据请求分配服务器,区分处理逻辑,加快响应