同源策略概述
(1)浏览器的同源策略:
浏览器为确保资源安全,而遵循的一种策略。
1.1 什么是源?
(不看路径)
1.2 同源与非同源
1.3 同源请求与非同源请求
[所处源』与『目标源』不一致,就是『非同源」又称「异源』或『跨域』
(2)浏览器会对跨域做出哪些限制?
例如: [源A] 和 [源B] ,它们是 [非同源] 的,则浏览器会有如下限制:
①DOM 访问限制:
[源A] 的脚本不能读取和操作 [源B] 的DOM
这么写就触发跨越了,拿不到iframe的document
② Cookie 访问限制:
[源A] 不能访问 [源B] 的cookie。
③Ajax 响应数据限制:
[源A] 可以给 [源B] 发请求,但是无法获取 [源B] 响应的数据。
浏览器对 Ajax 获取数据的限制是影响最大的一个,且实际开发中经常遇到。
注意:
1.跨域限制仅存在浏览器端,服务端不存在跨域限制。
2.即使跨域了,Ajax 请求也可以正常发出,但响应数据不会交给开发者
3.<link>、<script>、<img>…… 这些标签发出的请求也可能跨域,只不过浏览器对标签跨域不做严格限制(CSP),对开发几乎无影响。
CORS 解决 Ajax 跨域问题
(1)CORS 概述
CORS 全称:Cross-Origin Resource Sharing(跨城资源共享),是用于控制 浏览器校验 跨域请求的一套规范,服务器依照 CORS 规范,添加特定 响应头 来控制浏览器校验,大致规则如下:
- 服务器明确表示 拒绝跨域 请求,或没有表示,则浏览器校验不通过。
- 服务器明确表示 允许跨域 请求,则浏览器校验通过。
使用 CORS 解决跨域是最正统的方式,且要求服务器是“自己人“
(2)CORS 解决跨域
① 简单请求与复杂请求:
CORS 会把请求分为两类,分别是: ① 简单请求、②复杂请求
关于预检请求 perflight:
- 发送时机:预检请求在实际跨域请求之前发出,是由浏览器自动发起的。
- 主要作用:用于向服务器确认是否允许接下来的跨域请求。
- 基本流程:先发起 OPTIONS 请求,如果通过预检,继续发起实际的跨域请求。
- 请求头内容:一个OPTIONS 预检请求,通常会包含如下请求头:
② 简单请求解决方法:
整体思路: 服务器在给出响应时,通过添加 Access-Control-Allow-Origin 响应头,来明确表达允许某个源发起跨域请求,随后浏览器在校验时,直接通过。
因此需要 express 配置 Access-Control-Allow-Origin :
③ 复杂请求解决方法:
①服务器先通过浏览器的预检请求,服务器需要返回如下响应头:
②处理实际的跨域请求(与处理简单请求跨域的方式相同)
④ 借助 cors 库快速完成配置:
上述的配置中需要自己配置响应头,或者需要自己手动封装中间件,借助cors 库,可以更方便完成配置
JSONP 解决跨域问题
(1)概述
1.1 JSONP 概述:
JSONP 是利用了<script>标签可以跨域加载脚本,且不受严格限制的特性,可以说是程序员智慧的结晶,早期一些浏览器不支持 CORS 时,可以靠 JSONP 解决跨域(但是只能解决get请求)。
1.2 基本流程:
- 客户端创建一个<script>标签,并将其 src 属性设置为包含跨域请求的 URL,同时准备一个回调函数,这个回调函数用于处理返回的数据。
- 服务端接收到请求后,将数据封装在回调函数中并返回。
- 客户端的回调函数被调用,数据以参数的形势传入回调函数
(2)配置代理解决跨域:
(3)jQuery封装的JSONP:
配置代理解决跨域
(1)自己配置代理服务区
借助 http-proxy-middleware 配置代理
允许跨域并去掉api(通过代理服务器发送,因为服务器与服务器之间没有跨域限制)
⭕项目打包
- 我们开发用的脚手架其实就是一个微型服务器,用于:支撑开发环境、运行代理服务器等
- 打包完的文件中不存在:(.vue、.jsx、 .less 等文件,而是: HMTL、CSS、JS 等;
- 打包后的文件,不再借助脚手架运行,而是需要部署到服务器上运行
- 打包前,请务必梳理好前端项目的 Ajax 封装(请求前缀、代理规则等)
控制台输入:npm run build
生成的文件夹如下:
需要搞清楚项目的请求是怎么发出去的(联系哪台服务器,代理是怎么配置的),因此需要去组件中分析请求是如何送出去的。
- dispatch 集中式状态管理
- 并且进行命名空间的划分以及模块化的拆分
只看到一部分路径,因此需要 Ctrl + 继续点击 request 进去查看
协议还不是完整的(即协议名+主机名+端口号+路由)
localhost 即可能是脚手架配置了代理,由游览器发出去了请求到脚手架的代理,代理转发请求到有数据的服务器
即发给8080的请求转发给target,并且去掉了dev
因此真正的数据服务器请求如下:
http://sph-h5-api.atguigu.cn/api/product/getBaseCategoryList
本地服务器部署步骤
通过express:
npm i
nodemon server.js
会遇到如下问题:
①刷新页面404问题(前端重定向加入了 '/home' 游览器误以为后端路由)
1.哈希路由
- Hash 模式 (mode: 'hash'——URL 的 hash 部分(即 # 之后的部分)来管理路由): 优点:与服务器无关,页面刷新不会导致服务器错误,适用于没有服务器配置的应用。
- History 模式 (mode: 'history'——使用 HTML5 的 History API 来管理路由。它能提供更干净的 URL,不带 #): 需要服务器配置支持,确保所有的 URL 都能返回你的应用的入口 HTML 文件
2.无法匹配后端路由时返回index.html
(游览器地址栏发出的请求都是 get 请求。当匹配不上时就跳转index.html。当引入的JS能正常工作,前端路由就可以奏效了,就可以跳转login)
可以借助 connect-history-api-fallback 中间件完成配置
使用connect-history-api-fallback可以让配置更灵活,比如 /login 临时不需要作为前端路由处由
处理,就可以按照如下方式配置:
②Ajax请求没用
打包完后脚手架后的代理服务器不起作用了
/dev 即识别当前所出的主机名、协议名、主机名端口号
npm i http-proxy-middleware
(2)使用 Nginx 搭建代理服务器
Nginx(发音为“engine-x”)是一款高性能的 HTTP 服务器和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器。Nginx最初由 lgor Sysoev 编写,于 2004年发布。它以其高性能、高稳定性、丰富的功能集和低系统资源消耗而闻名,主要功能有:
- 反向代理
- 负载均衡
- 静态内容服务
- HTTP/2 支持
- SSL/TLS 支持
- 高速缓存
整体思路: 让 nginx 充当两个角色,既是 静态内容服务器,又是代理服务器。
1.修改 nginx 配置如下,注意 nginx 的根目录最好不是C盘
2.修改前端项目,让所有请求都转发给/dev,随后重新打包
3.随后直接访问 nginx 服务器即可,例如nginx 如果运行在 8099 端口,则访问:
4.随后会遇到刷新 404 问题,追加 nginx 配置来解决 :