全部前端工程师都知道跨域问题(不一样的协议、域、端口),也都知道解决跨域的常见方式是经过设置cors。 那么cors究竟是什么,它是如何解决跨域问题的呢前端
CORS全称Cross-Origin Resource Sharing,即跨域资源共享。是解决跨域问题常见的方式。api
知足如下条件即视为简单请求跨域
请求方法为如下任意方法之一(在W3C规范中也称为简单方法 simple method)浏览器
请求头只能包含如下字段 (在W3C规范中前4种称为简单头部 simple header,不包括浏览器自动设置的那些,好比User-Agent,Connection等)缓存
对于简单请求,浏览器会直接发起实际跨域请求,只要返回头部中设置了正确的Access-Control-Allow-Origin
字段便可成功请求,不然你会在浏览器的console
面板看到相似于下面这样报错cookie
Access to XMLHttpRequest at 'http://domain.com/api/test' from origin 'http://localhost:1234' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
前端工程师
对于非简单请求,在发起实际的请求以前,浏览器会发起一个预检请求(preflight request),这是个options请求,包含如下字段app
当预检请求经过后,才会发起真实的请求,不然你会在浏览器的console
面板看到相似于下面这样报错(这里是请求头没有经过预检)cors
Access to XMLHttpRequest at 'http://domain.com/api/test' from origin 'http://localhost:1234' has been blocked by CORS policy: Request header field custom-header is not allowed by Access-Control-Allow-Headers in preflight response.
dom
另外,须要同时对接口的options
方法以及真实的get
或post
方法设置对应的返回头。若是只设置了真实请求方法的返回头,而没有相应设置options方法的返回头,预检也不会经过。你会在浏览器的console
面板看到相似于下面这样报错
Access to XMLHttpRequest at 'http://domain.com/api/test' from origin 'http://localhost:1234' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
预检请求是有缓存的!在预检请求的返回头中设置Access-Control-Max-Age
字段,值为int类型,表明过时时间,单位是秒。 在该时间段以内,非简单方法发送跨域请求不会再事先发起预检请求。
对于预检请求,能够返回下列字段
Access-Control-Allow-Origin
不能为*
,当该值为false,同时请求又携带了credentials,该请求的返回会被浏览器忽略)本文主要知识来源并推荐阅读: