前后端分离项目,前后端请求访问通,首先需要解决跨域问题
什么是跨域,跨域的前提是什么?
跨域的产生来源于现代浏览器所通用的同源策略(包括ajax/fetch请求,dom渲染:比如iframe等,这样在一定程度上防止了 CSRF 攻击)
跨域主要是浏览器行为,是客户端浏览器的行为,浏览器根据同源策略,判断是否是跨域。
服务器端和服务器互相请求,是没有跨域这种说法的
浏览器出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头
所有请求都会产生跨域吗?
简单请求不会产生跨域,复杂请求才会产生跨域,
跨域请求截断
跨域的情况下,请求依然跨域到达服务器,并且服务器可以正常响应,并返回数据,服务器不会报错,但是由于浏览器的同源策略并没有把服务器的响应数据给到浏览器,浏览器会报错(浏览器F12,控制台跨域看到),因为违反了浏览器的同源策略。
预检请求是做什么的?
浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 COOKIEs 和 HTTP 认证相关数据),“预检请求” 的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。但是“预检请求”会有安全问题,泄漏服务器的允许方法类型等信息
OPTIONS:response字段包含允许的方法,表明服务器允许客户端使用 POST, GET 和 OPTIONS 方法发起请求。
Access-Control-Allow-Methods: POST, GET, OPTIONS
怎么解决跨域?
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器,让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。
跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
· Access-Control-Allow-Origin:接受的域名请求,*表示任意域名· Access-Control-Allow-Methods:允许的方法类型:get,put· Access-Control-Allow-Headers:· Access-Control-Allow-Credentials:true,允许携带凭证· Access-Control-Max-Age
Access-Control-Allow-Origin:浏览器根据接受到的响应头里的 Access-Control-Allow-origin 字段做匹配,若无该字段,说明不允许跨域,从而抛出一个错误,若有该字段,则对字段内容和当前域名做匹配,如果同源,则说明可以跨域,浏览器接受该响应,若不同源,则说明该域名不可跨域,浏览器不接受该响应,并抛出一个错误。通配符*,表示允许来自所有域的请求。
Access-Control-Allow-Credentials:一般而言,对于跨域 XMLHttpRequest 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。
对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。
这是因为请求的首部中携带了 COOKIE 信息,如果 Access-Control-Allow-Origin 的值为“*”,请求将会失败。
Access-Control-Allow-Headers:在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。
Access-Control-Expose-Headers 头让服务器把允许浏览器访问的头放入白名单,这样浏览器就能够通过getResponseHeader访问白名单内的响应头了。