CORS跨域请求

前言

相信不少前端开发人员都会遇到跨域请求的问题。或者在面试的时候,都会被问到如何解决跨域问题,有多少人是以为这个是前端必需要去解决的问题?实际上这个问题要先后端共同去解决的,咱们经常使用的方法不管是用jsonp仍是cors都是须要先后端一块儿去完成的。之因此写这篇文章就是最近在使用cors时,遇到了一些问题,在此进行总结一下加深印象。前端

项目状况

项目要求先后端须要部署在不一样的域名或者是不一样的端口下面,天然就会存在请求跨域的问题了,跟后台协商好用的解决方案是使用CORS方式。请求须要cookie,须要自定义请求头‘x-requested-with’,如下是后台设置的代码,正常这样设置是没问题的了 面试

前端也设置了请求头 withCredentials = true;最后的结果仍是不行,这就很奇怪了,百度看了不少解决方案都是同样的代码,为何这里就不行?请求携带cookie或有自定义请求头,origin也动态设置成对应发出请求的origin了。

postman、fetch测试

在postman上使用一样的请求(无‘x-requested-with’请求头,也无cookie)切换method进行测试,只有get和post会有状态码返回,其余的连状态码都没有,看上图的设置,options和delete理应也会有状态码返回的才对,这是就判断是否是后台代码在哪一个地方进行了拦截,连进CorsUtils的机会都没有。用fetch测试,带上‘x-requested-with’在控制台看到Request Method为OPTIONS,无响应体。另外在项目里测试的是一个post请求,携带了cookie和自定义请求头。接下来就了解下cors的存在的场景吧。json

cors场景

cors存在三种跨域请求场景,分别是简单跨域请求带预检(Preflighted)的跨域请求附带身份凭证的请求后端

简单跨域请求

当知足如下条件时,浏览器会认为是简单请求跨域

  • 请求方法是get,post或head,且Content-Type的值为application/x-www-form-urlencoded, multipart/form-data或着text/plain中的一个值;
  • 无自定义请求头

此时“Access-Control-Allow-Origin”设置成“*”,便可跨域访问,也能够设置成指定的域名,在上面所说的项目中也验证了这点,确实是能够跨域请求成功了。浏览器

带预检(Preflighted)的跨域请求

当知足如下任一条件时,浏览器会先发送一个OPTIONS的预检请求,当预检请求成功后,才会发送真正的请求cookie

  • 请求方法是put、delete、connect、options、trace和patch其中之一;
  • content-type的值是application/x-www-form-urlencoded, multipart/form-data和text/plain以外的;
  • 携带自定义请求头的;

到这里,结合项目用的请求(就是这里所说的带预检的请求)和上面的测试状况,就让后台去检查他使用的后台框架是否是在哪里对get和post之外的请求拦截调了,后台去检查后果真是后台框架上作了限制,根本就没有机会进入到上图粘出来的程序。至于后台作了什么我就不是很懂了这里就略过了。app

附带身份凭证的请求

另外项目须要作会话处理,须要使用到cookie,后台设置了“Access-Control-Allow-Credentials”为 true,前端也设置了请求头 withCredentials = true;这样请求就能把cookie带上了。这里要注意的是当请求须要附带身份凭证时,“Access-Control-Allow-Origin”要设置成指定域名,建议有跨域要求都设置成动态域名,不要设置“*”避免没必要要的麻烦。cors

总结

以上是在开发过程当中遇到的问题,针对这个问题的排查过程作了个回忆,并对cors跨域请求的知识作了个巩固。扎实的基础会对问题的排查节省不少时间,多总结,多积累。框架

若有错误的理解,烦请指出,谢谢阅读。

相关文章
相关标签/搜索