最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 解决跨域之CORS(附前后端DEMO源码)

    正文概述 掘金(Yayoi-zq)   2021-06-17   468

    前言

    CORS对于前端开发而言,应该是一个非常重要的问题,不过对于大部分项目来说都是前后端同源,因此也就不会涉及到CORS的问题,即便是面试时大部分人也只是知道个大概,没有人去深究其中的细节实现。

    直到前不久,我在开发过程中遇到了这方面的问题之后才查阅了一些资料,并详细地对CORS的机制进行了了解。因此这篇文也是给有类似经历的前端开发者写的,主要着重于实践中遇到的问题。文章后附有前后端代码可供参考。

    什么是CORS

    在讲CORS之前我们需要了解一下浏览器加载资源的机制:

    1. 同源策略,同源即两个 URL 的 protocol、port (en-US) (如果有指定的话)和 host 都相同的话,则这两个URL是同源。同源策略是一个重要的安全策略,它能够限制资源间的交互,帮助阻隔恶意文档,减少可能被攻击的媒介。
    2. 和同源策略相对的则是跨源,也就是我们常说的跨域,只要protocol、port和 host 有一个不同则为跨域。

    下表给出了与 URL store.company.com/dir/page.ht… 的源进行对比:

    URL结果原因
    store.company.com/dir2/other.…同源只有路径不同store.company.com/dir/inner/a…同源只有路径不同store.company.com/secure.html跨源协议不同store.company.com:81/dir/etc.htm…跨源端口不同 ( http:// 默认端口是80)news.company.com/dir/other.h…跨源主机不同

    同源策略这里不多讲了,对于大部分的项目前后端同源的话一般不会有什么问题。但当前后端分离部署产生跨域问题时,由于出于安全考虑浏览器是会限制跨域请求的,这时我们就可以采用CORS来解决问题。

    CORS即Cross-Origin Resource Sharing,中文译作跨域资源共享。CORS机制允许服务器通过标识除自己以外的域来允许浏览器访问这些跨域资源,也是我们处理跨域问题中常用的一种解决方式。

    (我相信大部分人在面试的时候对于跨域的解决方法都能张嘴就来,但实际操作的时候还真不一定就能非常熟练,所以还是实践出真知)

    简单请求与预检请求

    在CORS规范中,讲请求分为两种,即简单请求和预检请求。

    简单请求定义如下:

    • 使用方法为GETHEADPOST之一
    • 允许人为设定的头部字段(即对CORS安全的首部字段)
      • Accept
      • Accept-Language
      • Content-Language
      • Content-Type (有额外限制)
      • DPR
      • Downlink
      • Save-Data
      • Viewport-Width
      • Width
    • 请求中的任意XMLHttpRequestUpload对象均没有注册任何事件监听器;XMLHttpRequestUpload对象可以使用XMLHttpRequest.upload属性访问
    • 请求中没有使用 ReadableStream 对象

    其中Content-Type的值仅限以下三者之一:

    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

    满足以上条件的请求即为简单请求

    而不满足以上条件的请求则会触发预检请求。浏览器必须首先使用OPTIONS方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。"预检请求“可以避免跨域请求对服务器产生未预期的影响。 下图为一个预检请求的示例: 解决跨域之CORS(附前后端DEMO源码) 解决跨域之CORS(附前后端DEMO源码) 解决跨域之CORS(附前后端DEMO源码) 该请求为从localhost:8080发出到localhost:3000的一个GET请求,由于端口不同而产生了跨域请求。但是因为请求头header中携带了一个自定义的字段X-Custom-Header,因此触发了预检请求,预检请求通过后才进行GET请求。

    携带Cookie的请求

    CORS可以基于HTTP cookies和HTTP认证信息发送身份凭证。一般对于跨域请求浏览器不会发送身份凭证信息。想要发送凭证信息需要进行相应的设置:

    客户端中的请求进行如下设置后方能向服务端发送带有Cookie的请求:

    withCredentials: true
    

    服务端则需要对响应头设置:

    Access-Control-Allow-Credentials: true
    

    如果服务端未进行设置,则浏览器将不会把响应内容返回。

    解决跨域之CORS(附前后端DEMO源码) 解决跨域之CORS(附前后端DEMO源码)

    要注意的是,对于需要携带Cookie的请求,服务器不得设置Access-Control-Allow-Origin的值为*,这种情况下请求会失败,如下图: 解决跨域之CORS(附前后端DEMO源码)

    CORS设置

    下面就介绍一下常用的CORS设置。

    HTTP响应头字段

    Access-Control-Allow-Origin

    该字段指定了允许访问该资源的外域URI:

    Access-Control-Allow-Origin: http://localhost:8080
    

    上述设置允许来自http://localhost:8080 的请求访问该资源。也可以设置为通配符*表示允许所有域的请求访问资源。对于需要携带Cookie的请求服务器可以指定值为通配符。

    Access-Control-Expose-Headers

    在跨源访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头。默认情况下只有以下七种响应头可以暴露给外部:

    • Cache-Control
    • Content-Language
    • Content-Type
    • Content-Length
    • Expires
    • Last-Modified
    • Pragma

    如果要访问其他头,则需要服务器设置本响应头。

    Access-Control-Expose-Headers: X-Kuma-Revision, X-Custom-Header
    

    上述设置将两个自定义的响应头暴露给浏览器。我们看下下图所示的例子:

    解决跨域之CORS(附前后端DEMO源码)

    解决跨域之CORS(附前后端DEMO源码)

    服务端自定义了一个X-Expose-Headers的响应头,但没有设置Access-Control-Expose-Headers,因此即使在浏览器打印响应对象,headers中也是拿不到的。

    Access-Control-Max-Age

    用于指定预检请求的结果能够被缓存多久。

    Access-Control-Max-Age: 3600
    

    上述设置表示预检请求的结果将在3600秒内是有效的。

    Access-Control-Allow-Credentials

    用于指定当浏览器的credentials设置为true时是否允许浏览器读取response的内容。当用在对预检请求的响应中时,它指定了实际的请求是否可以使用credentials,详见上一节。

    Access-Control-Allow-Methods

    用于预检请求的响应。指明了实际请求所允许使用的 HTTP 方法。

    Access-Control-Allow-Methods: PUT, GET, POST, DELETE
    

    上述设置表示该请求允许使用PUT、GET、POST、DELETE方法调用。

    Access-Control-Allow-Headers

    用于预检请求的响应。其指明了实际请求中允许携带的首部字段。

    Access-Control-Allow-Headers: token, originalUrl
    

    以上设置表示实际请求中允许携带名为token和originalUrl的首部字段。

    HTTP请求头字段

    下面列出了可用于发起跨域请求的首部字段,这些字段不需要开发者手动设置。

    Origin

    Origin字段表明预检请求或实际请求的源站。

    Access-Control-Request-Method

    用于预检请求,作用是将实际请求所使用的 HTTP 方法告诉服务器。

    Access-Control-Request-Headers

    用于预检请求。作用是将实际请求所携带的首部字段告诉服务器。

    DEMO源码

    github.com/Yayoiqz/cor… 上述的CORS设置DEMO中都有,可以调试。

    参考

    1. 跨源资源共享(CORS)
    2. 深入理解 CORS

    起源地下载网 » 解决跨域之CORS(附前后端DEMO源码)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元