Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ajax跨域完全讲解 #22

Open
liujie2019 opened this issue Mar 16, 2019 · 0 comments
Open

ajax跨域完全讲解 #22

liujie2019 opened this issue Mar 16, 2019 · 0 comments

Comments

@liujie2019
Copy link
Owner

1. 产生跨域问题的原因

  1. 浏览器限制(出去安全原因)
  2. 跨域
  3. XHR请求

2. 解决思路

image

  1. 浏览器限制(基于同源策略的安全检查),取消安全检查;
  2. jsonp:实现jsonp、不好用(让发出的请求变为不是XHR的类型);
  3. xhr:两种方法 一种:被调方(修改服务器,支持跨域)。第二种:调用方,通过实现代理的方式(隐藏跨域)。
2.1 浏览器禁止检查:命令行参数启动
  1. 终端输入:C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security
  2. 如果方法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的弊端:

  1. 需要服务器改动代码;
  2. 只支持GET请求;
  3. 发送的不是xhr请求。

image

jsonp方式发出的请求为script类型。

image

客户端->http服务器->应用服务器,然后从,应用服务器->http服务器->客户端。

image

Apache/nginx为http静态服务器,用来处于静态请求或者负载均衡。

2.3 被调用方解决-支持跨域

image

跨域请求和非跨域请求的区别:跨域请求的请求头中多了Origin字段,即当前域名。
image

表示允许所有的域名和方法。

2.4 简单请求和非简单请求
  1. 简单请求:先执行后检测;
  2. 非简单请求:先预检,后执行。
  3. OPTIONS:预检命令
  4. OPTIONS缓存:Access-Control-Max-Age指定缓存预检请求的时间。

非简单请求每次都要发送两条请求,效率很低,可以通过将预检请求缓存来减少请求数量,设置方法是服务端响应头设置Access-Control-Max-Age,值是预检请求缓存时间,如下所示:

// 缓存预检请求1个小时
"Access-Control-Max-Age": "3600"

image
image

2.5 带Cookie的跨域
$.ajax({
    type: "get",
    xhrFields: {
        widthCredentials: true // 发送ajax请求的时候会带上cookie
    }
})
  1. cookie是加在被调用方;
  2. 读cookie只能读到本域的。

不允许设置:Access-Control-Allow-Origin: *;,必须指定为特定的域名。

// enable cookie
res.addHeader("Access-Control-Allow-Credentials", "true")

当产生跨域的时候,请求头中会多一个字段,叫做origin,这个字段存储着当前域的信息。所以在发送带cookie的请求,后台又不知道调用方的域的信息时,可以先取到请求头中origin字段的值,然后再赋值给响应头的access-control-allow-origin字段。
image

2.6 带自定义头的跨域

image

2.7 被调用方解决跨域-nginx解决方案

虚拟主机:多个域名指向同一个服务器,服务器根据不同的域名把请求转到不同的应用服务器。看上去有多个主机,实际上只有一个主机。

nginx配置:

server {
    listen 80; // 监听的端口
    server_name b.com; // 监听的域名
    // 所有的请求都转发到这个地址
    location /{
        proxy_pass http://localhost:8080/;
    }
}

image

nginx配置跨域:

server {
    listen 80; // 监听的端口
    server_name b.com; // 监听的域名
    // 所有的请求都转发到这个地址
    location /{
        proxy_pass http://localhost:8080/;
    }
}
2.8 被调用方解决跨域-apache解决方案

image

2.9 调用方解决跨域-隐藏跨域

反向代理:访问同一个域名的不同url,最后去到两个不同的服务器。

反向代理-nginx配置:

image

反向代理-apache配置:

image
image

当前请求地址:

image

参考文档

  1. Nginx 解决API跨域问题
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant