什么是跨域
什么是Cross-origin_resource_sharing? 跨域请求存在的原因:由于浏览器的同源策略,即属于不同域的页面之间不能相互访问各自的页面内容。
跨域场景
域名不同
二级域名相同,子域名不同
- a.jiuyescm.com和b.jiuyescm.com为子域不同
端口不同,协议不同
解决跨域的方式
- jsonp
- 安全性差,已经不推荐
- CORS(W3C标准,跨域资源共享 - Cross-origin resource sharing)
- 服务端设置,安全性高,推荐使用
- websocke
- 特殊场景时使用,不属于常规跨域操作
- 代理服务(nginx)
- 可作为服务端cors配置的一种方式,推荐使用
如何处理跨域(CORS处理方式)
常见错误
No 'Access-Control-Allow-Origin' header is present on the requested resource
,并且The response had HTTP status code 404
1
XMLHttpRequest cannot load http://b.domain.com, Response to preflinght request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.domain.com' is therefore not allowed access. The Response had HTTP status code 404.
问题原因:服务器端后台没有允许OPTIONS请求
No 'Access-Control-Allow-Origin' header is present on the requested resource
,并且The response had HTTP status code 405
1
XMLHttpRequest cannot load http://b.domain.com, Response to preflinght request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.domain.com' is therefore not allowed access. The Response had HTTP status code 405.
问题原因:服务器端后台允许了OPTIONS请求,但是某些安全配置阻止了OPTIONS请求
No 'Access-Control-Allow-Origin' header is present on the requested resource
,并且The response had HTTP status code 200
1
XMLHttpRequest cannot load http://b.domain.com, Response to preflinght request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.domain.com' is therefore not allowed access.
问题原因:服务器端后台允许了OPTIONS请求,并且OPTIONS请求没有被阻止,但是头部不匹配。
heade contains multiple values '*,*'
,并且The response had HTTP status code 200
1
XMLHttpRequestcannot load http://b.domain.com. The 'Access-Control-Allow-Origin' header contains multiple values'*, *', but only one is allowed. Origin 'http://a.domain.com' is therefore notallowed access.
问题原因:设置多次Access-Control-Allow-Origin=*,可能是配置的人对CORS实现原理和机制不了解导致。
OPTIONS请求?
有时你会发现明明请求的是POST、GET、PUT、DELETE,但是浏览器中看到的确实OPTION,,为什么会变成OPTION?
原因:因为本次Ajax请求是“非简单请求”,所以请求前会发送一次预检请求(OPTIONS),这个操作由浏览器自己进行。如果服务器端后台接口没有允许OPTIONS请求,将会导致无法找到对应接口地址,因此需要服务端提供相应的信息到response header中,继续往下看。
后端需要返回的Header
1 | # 服务端允许访问的域名 |
如果跨域需要携带cookie去请求,Access-Control-Allow-Credentials必须为true,但是需要注意当Access-Control-Allow-Credentials=true时,Access-Control-Allow-Origin就不能为” * “ ,必须是明确的域名,当然可以多个域名使用 “,” 分割