ajax跨域完全讲解
Opened this issue · 0 comments
liujie2019 commented
1. 产生跨域问题的原因
- 浏览器限制(出去安全原因)
- 跨域
- XHR请求
2. 解决思路
- 浏览器限制(基于同源策略的安全检查),取消安全检查;
- jsonp:实现jsonp、不好用(让发出的请求变为不是XHR的类型);
- xhr:两种方法 一种:被调方(修改服务器,支持跨域)。第二种:调用方,通过实现代理的方式(隐藏跨域)。
2.1 浏览器禁止检查:命令行参数启动
- 终端输入:
C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security
; - 如果方法1不行,通过
everyting
软件找到chrome.exe
所在的路径,在chrome.exe
所在的路径按下shift
键,点击右键,点击“在此处打开命令行窗口”,然后输入chrome --disable-web-security
。
chrome --disable-web-security --user-data-dir=g:\temp3
2.2 jsonp(JSON with Padding)
jsonp
返回的是js
代码,不是json
对象。
content-type
:发送信息至服务器时内容编码类型,即客户端发送请求数据的类型;ajax
的属性添加cache:true
,表示结果可以被缓存,请求的链接中就没有_=某个值;
jsonp
的弊端:
- 需要服务器改动代码;
- 只支持
GET
请求; - 发送的不是
xhr
请求。
jsonp
方式发出的请求为script类型。
客户端->http服务器->应用服务器,然后从,应用服务器->http服务器->客户端。
Apache/nginx为http静态服务器,用来处于静态请求或者负载均衡。
2.3 被调用方解决-支持跨域
表示允许所有的域名和方法。
2.4 简单请求和非简单请求
- 简单请求:先执行后检测;
- 非简单请求:先预检,后执行。
- OPTIONS:预检命令
- OPTIONS缓存:
Access-Control-Max-Age
指定缓存预检请求的时间。
非简单请求每次都要发送两条请求,效率很低,可以通过将预检请求缓存来减少请求数量,设置方法是服务端响应头设置Access-Control-Max-Age
,值是预检请求缓存时间,如下所示:
// 缓存预检请求1个小时
"Access-Control-Max-Age": "3600"
2.5 带Cookie的跨域
$.ajax({
type: "get",
xhrFields: {
widthCredentials: true // 发送ajax请求的时候会带上cookie
}
})
- cookie是加在被调用方;
- 读cookie只能读到本域的。
不允许设置:Access-Control-Allow-Origin: *;
,必须指定为特定的域名。
// enable cookie
res.addHeader("Access-Control-Allow-Credentials", "true")
当产生跨域的时候,请求头中会多一个字段,叫做origin
,这个字段存储着当前域的信息。所以在发送带cookie
的请求,后台又不知道调用方的域的信息时,可以先取到请求头中origin
字段的值,然后再赋值给响应头的access-control-allow-origin
字段。
2.6 带自定义头的跨域
2.7 被调用方解决跨域-nginx解决方案
虚拟主机:多个域名指向同一个服务器,服务器根据不同的域名把请求转到不同的应用服务器。看上去有多个主机,实际上只有一个主机。
nginx配置:
server {
listen 80; // 监听的端口
server_name b.com; // 监听的域名
// 所有的请求都转发到这个地址
location /{
proxy_pass http://localhost:8080/;
}
}
nginx配置跨域:
server {
listen 80; // 监听的端口
server_name b.com; // 监听的域名
// 所有的请求都转发到这个地址
location /{
proxy_pass http://localhost:8080/;
}
}
2.8 被调用方解决跨域-apache解决方案
2.9 调用方解决跨域-隐藏跨域
反向代理:访问同一个域名的不同
url
,最后去到两个不同的服务器。
反向代理-nginx配置:
反向代理-apache配置:
当前请求地址: