ajax 跨域原因:
- 浏览器限制 (chrome –disable-web-security –user-data-dir=e:\temp3)
- 跨域
- XHR [XMLHttpRequest] (JSONP 解决)
JSONP 有什么弊端
- 服务器需要改动代码支持
- 只支持 GET 请求
- 发送的不是 XHR 请求 (不支持异步及各种事件)
跨域解决方向
被调用方解决 (设置 header,允许跨域)
- 服务器端实现
- NGINX 配置
- APACHE 配置
1
2
3
4header("Access-Control-Allow-Origin: *")
header("Access-Control-Allow-Methods: *")
header("Access-Control-Allow-Headers: Content-Type") // 针对预检命令
header("Access-Control-Max-Age: 3600") // 针对预检命令缓存,单位是秒
调用方解决 (设置代理访问,隐藏跨域)
简单请求和非简单请求
- 定义
- OPTIONS 预检命令
- OPTIONS 预检命令缓存
工作中比较常见的【简单请求】:
方法为:
- GET
- HEAD
- POST
请求 header 里面
- 无自定义头
- Content-Type 为以下几种:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
工作中常见的【非简单请求】有:
- put, delete 方法的 ajax 请求
- 发送 json 格式的 ajax 请求
- 带自定义头的 ajax 请求
带 cookie 的跨域
带 cookie 的时候, origin 必须是全匹配,不能用 *
1
header("Access-Control-Allow-Origin: http://localhost:8081")
要新加一个头
1
header("Access-Control-Allow-Credentials: true")
1 | // 带 cookie 的 $.ajax 请求需要配置 |
注: 可以通过 document.cookie 来设置和获取 cookie | cookie 要加在被调用方,因为网络请求里面你要读的 cookie 只能读到本域的
带自定义头的跨域
1 | // 带自定义头的 $.ajax 请求需要配置 |
后台需要配置:1
header("Access-Control-Allow-Headers: Content-Type, x-header1, x-header2")
后台代码逻辑可以为:取到 Access-Control-Allow-Headers 不为空的话,就设置1
2
3
4String headers = req.getHeader("Access-Control-Allow-Headers");
if(!isEmpty(headers)){
header("Access-Control-Allow-Headers: " + headers)
}
被调用方 - nginx 解决跨域
1 | server{ |
被调用方 - APACHE 解决方案
1 | // 需要打开虚拟主机的相关配置 |
1 | // httpd-vhosts.conf |
被调用方 - SPRING 框架解决方案
增加 @CrossOrigin 注解(可以加在类上面,也可以加在具体的方法上面)
调用方解决 - 隐藏跨域
通过调用方的 http 服务器的反向代理转发到被调用方的服务器,在浏览器上看不到任何跨域请求
反向代理(简单来说就是:同一个域名的两个不同的 URL,它最后会去到两个不同的服务器)
隐藏跨域与通过被调用方解决方案相比,调用方解决方案时,调用的接口都是本域的,所以调用接口的 URL 都是相对地址
1 | // NGINX 的配置 |
1 | // APACHE 的配置 |