本文主要分为四个部分:

  • 跨域的原理
  • 什么是 CORS
  • 如何实现 CORS
  • CORS 如何调试

为什么会有跨域问题出现?

跨域问题的本质原因是:浏览器通过同源策略来防止恶意网站窃取数据。

那么什么是同源策略呢?同源是指:协议、域名、端口都相同,非同源的资源之间不能相互通信。同源策略是为了保证用户信息的安全,防止恶意的网站窃取数据。

然而,同源策略的存在也导致不同源之间的合理通信也受到了限制:

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM 无法获得
  • AJAX 请求不能发送

为了解决浏览器同源策略给我们的限制,各种跨域方案纷纷涌现,这篇文章主要介绍 CORS 这种解决方案。

什么是 CORS?

CORS是一种W3C标准,它允许服务器通过一些自定义的头部来限制哪些源可以访问它自身的资源。

CORS还规定对于一些可能对服务器数据产生副作用的http请求,需要在正式请求被发出之前,先发送一个options的预检请求,获知服务器是否允许该跨源请求。

预检请求一般发发生在下列情况中:

  • 使用GET或POST以外的方法;
  • 利用POST发送application/x-www-form-urlencoded, multipart/form-data, or text/plain之外的Content-Type;例如,post body的Content-type为application/xml
  • 发送自定义的头部信息,如x-pagination-count

注意:跨域并非是浏览器限制了发起请求,也可能是跨域请求其实可以发出去,但是返回结果被浏览器拦截了

如何实现 CORS

其实,实现 CORS 通信的关键在于 服务器。

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

那么服务端应该怎么做呢?

服务器需要在响应头部中配置一些与跨源有关的字段

Access-Control-Allow-Origin
origin 参数的值指定了允许访问该资源的外域 URI。
对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符*,表示允许来自所有域的请求Access-Control-Expose-Headers
在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头
例如前后端协作时,分页信息要储存在header头部,需要设置 x-pagination-countAccess-Control-Allow-Headers
指明了实际请求中允许携带的首部字段Access-Control-Allow-Credentials
指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容。
当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。Access-Control-Max-Age
指定了preflight请求的结果能够被缓存多久(多少秒)Access-Control-Allow-Methods
指明了实际请求所允许使用的 HTTP 方法Access-Control-Allow-Headers 和 Access-Control-Expose-Headers 的区别access-control-allow-headers:实际request请求中可以带上哪些头部access-control-expose-headers:指的是浏览器发出 the actual request 得到 response, 浏览器可以使用/读取哪些 response 中的 headers

需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为*,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

CORS 的调试

分析 headers

大部分的 CORS 错误都可以归因与请求头和响应头的不匹配。

所以,CORS 出现错误,分析的第一个动作就是分析 headers,大部分的 CORS 错误都可以归因与请求头和响应头的不匹配,例如:

请求头中定义了 Access-Control-Request-Method: POST 以及 Access-Control-Request-Headers: authorization,content-type, 但是服务端没有与之匹配的响应头,所以报错。

辅助工具

浏览器的开发者工具

需要关注 console 和 network 两个面板,这个是我们最常用的方法,以后可以收集一些常见报错放上来,现在不多赘述。

抓包工具

简单请求(没有预检请求的那种)浏览器是不会给你展示具体的请求信息(响应头和请求头),这个时候你要怎么查看头部信息来定位问题呢?可以使用网络抓包工具,常用的有 Wireshark或Fiddler。

(使用教程网上很多,可以自行搜索查看)

curl

要用curl来模拟跨域请求(其实关键是模拟options请求),我们需要先来观察一下options请求的特征:

  • 具有OPTIONS的HTTP方法
  • Origin标头
  • Access-Control-Request-Method标头。

所以要使用curl模拟预检请求,我们需要模仿这三个特征。

(同样的道理也适用于postman,反正关键是你要设定正确的请求头才能模拟出 options请求)

curl --verbose -H "Origin: http://localhost:9090" -H "Access-Control-Request-Method: POST" -X OPTIONS http://xxx.xxx.xxx:8080/a/b

下图是curl的全部内容:

反正这里的请求结果里,如果响应的状态码不是200,那你就大胆地去和后端 battle 吧(当然前提是你已经正确设置了请求头,模拟出来的确实是options请求)

总结

无论使用什么辅助工具,其实总结起来就是三步:

  1. 关注请求和响应头
  2. 比较headers以查看是否存在不匹配的
  3. 解决问题
    1. 更新客户端的 request headers 以发送正确的请求
    2. 更新服务器的 response headers 以允许客户端来请求

本文同步发表在我的掘金专栏:

前端 er 需要知道的 CORS​juejin.im

前端跳转页面 添加request headers_前端需要了解的 CORS 知识相关推荐

  1. js layui跳转页面_【WEB前端开辟】layui的iframe跳转链接与页面按钮跳转相干引见...

    一.导航跳转iframe页面题目: 引荐:layui教程 关于layui的iframe嵌套页面的导航跳转页面题目,如下图所示能够看到结果: 在模板页的导航代码: 一切商品 商品列表 商品属性 商品分类 ...

  2. android上方导航条跳转页面,《成为大前端》系列 7. 多页面、页面跳转和Navigation模块...

    介绍 开发过移动 Web 页面的同学都知道,单个页面由客户端的 UI 所承载,页面间的跳转也 不再是使用 window 和 location,也不是使用 a 标签,而且调用 Native 写好的 br ...

  3. 【vue-router①】router-link跳转页面传递参数 - 进击的前端之路(偶尔爬坑java小路) - SegmentFault 思否

    在vue项目中,往往会遇到这样的情况,就是要实现在一个循环列表中,点击其中一条跳转到下个页面,然后将这一条的相关数据带到下个页面中显示,这是个循环列表,无论点哪一条都是跳到相同的页面,只是填的数据不一 ...

  4. 前端md转html添加样式_前端文档站点搭建方案

    ? 这是第 46篇不掺水的原创,想要了解更多,请戳上方蓝色字体:政采云前端团队关注我们吧- 本文首发于政采云前端团队博客:前端文档站点搭建方案 https://www.zoo.team/article ...

  5. 页面布局的方式——前端

    页面布局的方式--前端 文章目录 页面布局的方式--前端 页面布局的方式 双飞翼布局 多栏布局 弹性布局(Flexbox) 瀑布流布局 流式布局(Fluid) 响应式布局 注 页面布局的方式 页面布局 ...

  6. 服务器显示url过长,post跳转页面避免414提示url过长

    414状态码 在前端中,411 Length Required服务器无法处理客户端发送的不带Content-Length的请求信息,有的时候面对这种情况会比较心碎,基本思路如下: 压缩参数 使用pos ...

  7. Ajax+SpringBoot+Thymeleaf使用中遇到的跳转页面问题

    前言:这周在使用 Ajax+Thymeleaf 时遇到一个问题,折腾了我很久,在此记录一下 Ajax+SpringBoot+Thymeleaf使用中遇到的跳转页面问题 问题描述 我的目的:通过 Aja ...

  8. 前端页面添加灰色滤镜,使网页整体变灰

    前端页面添加灰色滤镜,使网页整体变灰 修改css样式 只需要在html的样式里面加一句代码 html,body,div,img{-webkit-filter: grayscale(100%);-moz ...

  9. 前端-html 点击 跳转页面

    html 点击 跳转页面 第一种: 在 button 标签加上 onclick 属性,使用 window.location.href='url' 进行跳转 <input type="b ...

最新文章

  1. php字符串比较函数
  2. DNN和IBatis.Net几乎同时发布新版本
  3. linux java 栈_关于Java中栈与堆的思考
  4. wxWidgets:wxColour类用法
  5. OpenCV如何启用Halide后端以提高效率
  6. 机器学习下一个万亿级的增长从哪来?
  7. 分析mrp主要应用范围_华珀聚脲丨聚脲的主要应用范围
  8. 【GPU编程】开始Cg之旅,编译自己的第一个Cg程序
  9. 多媒体领域顶会,ACM MM 2020 会议论文下载
  10. Kernel Method核方法—应用与理解
  11. buuct 假如给我三天光明 misc_假如给我三天光明读后感
  12. 企业级nginx服务优化(三 )Apache+防盗链
  13. html text-decoration,如何使用text-decoration
  14. IntelliJ IDEA 13怎么创建JAVA SE项目
  15. 一个函数中写多少行代码比较合适呢?
  16. 素数快速求法 -- 筛法求素数
  17. 华为android9升级包,华为Mate9官方固件ROM刷机包
  18. JAVA导出EXCEL——POI(转)
  19. ASP.NET Core2.1 你不得不了解的GDPR(Cookie处理)
  20. JavaScript 隐式类型转换

热门文章

  1. 基于JAVA+SpringMVC+MYSQL的城市公交查询系统
  2. 小红书:笔试题(棋盘最短路径,笔记本草稿栈,迷宫游戏)
  3. mysql导出表数据
  4. 查看提交历史(git log)
  5. [Android] SharedPreference的使用
  6. [沈航软工教学] 团队项目地址汇总
  7. 数组用法以及引用类型和值类型
  8. ecshop轻松实现不同商品调用不同模板
  9. Part1: Specification of Required Functions
  10. 正则表达式 匹配标签里面的值 eg:image input