什么是跨域?
简单的说,协议,域名,端口号有一个不一样就会有跨域。
跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 B 网站,包括提交内容和获取内容。由于安全原因,跨域访问是被各大浏览器所默认禁止的,XmlHttpRequest也不例外。
Nginx代理
这种方式比较简单,将A应用和B应用都通过一个统一的地址进行转发,这样就可以避免跨域问题出现。
server {
listen 80;
server_name www.gameloft9.top;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /manager {
proxy_pass http://127.0.0.1:6108/manager;
proxy_set_header Host $http_host;
}
location /service {
proxy_pass http://127.0.0.1:9200/service;
proxy_set_header Host $http_host;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
}
在上面的配置中,manager和service属于不同的域(IP虽然一样,但是端口不一样),如果manger里面的js调用service里面的接口,会报跨域错误。通过nginx转发后,所有的域都映射到www.gameloft9.top了,然后通过/manager,/service分别转发到各自的应用中,巧妙的避免了跨域问题。如果是纯前端项目,可以直接托管到nginx里面,也可以解决跨域问题,原理一样。
JSONP
因为< script>标签不受跨域限制,因此在此基础上出现了JSONP的ajax请求方式。通过包装一个< script>标签,去请求接口,然后返回数据及回调函数,这样就达到了跨域的目的。
JSONP的请求方式,需要设置dataType为"jsonp",表明这是一个jsonp的请求,jsonp是指定查询字符串中回调函数的参数的名称,jsonpCallback指定的是查询字符串中回调的函数名。
设置Access-Control-Allow-*头
jsonp的方式虽然简便,但有个缺点,就是只支持get请求,对于只支持post的接口就不支持了。通过后台设置Access-Control-*等header,可以解决跨域问题,而且get,post都支持。
Access-Control-Allow-Origin设置允许跨域的白名单,在白名单里的跨域请求是允许的。
Access-Control-Allow-Methods设置接受的方法,这里只接受POST方法。
Access-Control-Allow-Headers设置接受的请求头,用逗号分隔。
Access-Control-Allow-Max-Age设置预检的有效期,单位为秒。发送正式请求前,浏览器会预先发送一个预检请求,如果服务器返回了上述信息,表明是可以跨越请求的,然后才会正式发送请求。预检成功后,在有效期内就不用再发送了。