实际跨域问题及其解决方案
1.课题:ajax实现跨域访问
2.背景:
1.画面服务器:192.168.196.6 → tomcat服务
2.js模板服务器:192.168.196.8 → nginx服务
3.画面服务需跨域请求js资源
3.错误:
过程中经过了几次配置,出现过以下错误
1.No 'Access-Control-Allow-Origin' header is present on the requested resource,The response had HTTP status code 404
2.No 'Access-Control-Allow-Origin' header is present on the requested resource,The response had HTTP status code 405
4.解决:
nginx服务配置(nginx.conf):
location xxx {
alias xxx;
--允许GET请求,GET请求时返回以下头信息
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Headers' 'X-Requested-With';
}
--允许预检请求,预检请求时返回以下头信息
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'X-Requested-With';
add_header 'Content-Length' 0;
return 204;
}
}
分析:
1.我的跨域请求是GET方法,所以只配置GET就好用了。
2.我的请求是非简单请求,所以需要给预检请求(OPTIONS)配置接口。
学习与总结
CORS理解
CORS是一个W3C标准,全称是Cross-origin resource sharing(跨域资源共享)。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
CORS分类
浏览器将CORS请求分成两类:
- 简单请求(simple request)
- 非简单请求(not-so-simple request)
简单请求
-
满足以下两个条件就是简单请求
- (1) 请求方法是以下三种方法之一: HEAD,GET,POST
-
(2) HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
-
请求过程
1.浏览器直接发出CORS请求。跟普通请求相比,增加一个Origin字段。GET /cors HTTP/1.1 Origin: http://192.168.196.160 Host: xxx Accept-Language: xxx Connection: xxx User-Agent: xxx
2.如果Origin指定的域名在许可范围内,服务器返回的响应,会多出头信息字段Access-Control-Allow-Origin(也可能多出其他可选字段)
Access-Control-Allow-Origin: http://192.168.196.160 //或者是 *,表示接受任意域名的请求。 Content-Type: text/html; charset=utf-8
非简单请求
- 简单请求以外就是非简单请求。非简单请求就是对服务器有特殊的请求,比如请求方法是PUT或DELETE,或者Content-Type字段类型是application/json。
-
非简单请求会在请求之前增加"预检"请求(prelight)。
-
预检请求
- 浏览器询问服务器,当前网页所在域名是否在服务器访问许可名单(Origin),是否允许该请求方法(Access-Control-Request-Method)和头信息字段(Access-Control-Request-Headers)。
-
服务器得到预检请求后,检查Origin,Access-Control-Request-Method,Access-Control-Request-Headers字段,
-
如果确认允许跨域请求,就可以HTTP回应中带上这三个头信息,如下
Access-Control-Allow-Origin: 请求源域名或者* Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header
-
如果不允许跨域请求,服务器返回正常相应,但是不带cors头信息字段,浏览器就会触发错误如下
XMLHttpRequest cannot load 请求源域名 Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
-
-
- 预检请求通过后,以后每次浏览器的正常cors请求都跟简单请求一样。请求头信息会带着origin,服务器的响应也都会有头信息字段Access-Control-Allow-Origin。(参考简单请求)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。