什么是跨域?
要了解跨域,先要说说同源策略。同源策略是由 Netscape 公司提出的一个著名的安全策略,所有支持 JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当页面在执行一个脚本时会检查访问的资源是否同源,如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
DOM同源策略:禁止对不同源页面DOM进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。XmlHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。
跨域,指的是从一个域名去请求另外一个域名的资源。即跨域名请求!跨域时,浏览器不能执行其他域名网站的脚本,是由浏览器的同源策略造成的,是浏览器施加的安全限制。
跨域的严格一点来说就是只要协议,域名,端口有任何一个的不同,就被当作是跨域。
为什么要跨域?
现实工作开发中经常会有跨域的情况,因为公司会有很多项目,也会有很多子域名,各个项目或者网站之间需要相互调用对方的资源,避免不了跨域请求。
跨域解决方案
方案一:nginx配置代理
说明:前台通过域名的访问路径改变,代理到后台服务器地址。如下:红色配置代码
server {
listen 80;
server_name a.jd.com
access_log /export/servers/nginx/logs/a.jd.com_access.log realaddr_43703;
error_log /export/servers/nginx/logs/a.jd.com_error.log warn;root /export/Instances/car-plus/runtime/;
error_page 302 = http://www.jd.com/error2.aspx;
index index.html;
location / {
try_files $uri $uri/ index.html index.htm;
}
location ~^/myClient {
proxy_pass http://b.jd.com;
}
}
优点:操作简单、配置速度快
缺点:接口后台流量会经过前台的服务器,展现给用户。导致整个接口的性能会增加前端服务器这一层限制。
方案二:服务器后台设置允许跨域
说明:后台代码直接设置允许跨域
import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import javax.servlet.annotation.WebFilter; /** * 跨域设置 */ @Order(1) @Configuration @WebFilter(filterName = "corsDomainFilter", urlPatterns = {"*"}) @Slf4j public class CorsDomainFilter extends CorsFilter { public CorsDomainFilter() { super(configurationSource()); } private static UrlBasedCorsConfigurationSource configurationSource() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", corsConfig()); return source; } private static CorsConfiguration corsConfig() { log.info("跨域拦截init"); CorsConfiguration corsConfiguration = new CorsConfiguration(); //请求常用的三种配置,*代表允许所有,当时你也可以自定义属性(比如header只能带什么,只能是post方式等等) corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.setAllowCredentials(true); corsConfiguration.setMaxAge(3600L); return corsConfiguration; } }
优点:不受前台服务器的限制(网络、CPU性能等)
缺点:需要改变后台调整代码
方案三:服务器后台nginx配置
说明:服务器nginx后台配置响应结果允许跨域。
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($http_origin = https://a.jd.com){
add_header Access-Control-Allow-Methods POST;
#设置预检请求的缓存
add_header Access-Control-Max-Age 3600;
#允许Cookie
add_header Access-Control-Allow-Headers "Content-Type";
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Origin https://car.m.jd.com;
}
if ($http_origin = http://a.jd.com){
add_header Access-Control-Allow-Methods POST;
#设置预检请求的缓存
add_header Access-Control-Max-Age 3600;
add_header Access-Control-Allow-Headers "Content-Type";
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Origin http://car.m.jd.com;
}
proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://tomcat_gw.car.jd;
include /export/servers/nginx/conf/error/error_location.conf;
expires 0;
}
优点:不受前台服务器的限制(网络、CPU性能等),也不需要调整代码。
缺点:服务端需要nginx+tomcat