跨域那点事儿
一、 为什么要跨域
因为浏览器的同源策略导致的。默认情况下,JavaScript在发送AJAX请求时,URL的域名必须和当前页面完全一致。换句话说就是如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源,访问不受限制;否则则为跨源(跨域),限制访问。
为什么要有同源策略
可以抵御CSRF攻击浅谈CSRF攻击方式,跨站请求伪造-CSRF
CSRF攻击简单地说,是攻击者借助受害者的 Cookie 骗取服务器的信任,在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。
二、怎么跨域?
既然跨域必须存在,而我们又必须绕不过它,那我们该如何解决呢?
以下介绍跨域的两种方式
1,Nginx代理
使用Nginx部署在同一个域。我们请求的时候还是用前端的域名,Nginx可以帮我们把这个请求转发到真正的后端域名上,就可以避免跨域了。
server{
# 监听9099端口
listen 9099;
# 域名是localhost
server_name localhost;
#凡是localhost:9099/api这个样子的,都转发到真正的服务端地址http://localhost:9871
location ^~ /api {
proxy_pass http://localhost:9871;
}
}
2,CORS
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)跨域资源共享 CORS 详解。看名字就知道这是处理跨域问题的标准做法。
CORS需要浏览器和服务器同时支持,服务器需做如下设置:
跨域流程
后端具体做法
在网关中定义“GulimallCorsConfiguration”类,该类用来做过滤,允许所有的请求跨域。
@Configuration
public class GulimallCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter(){
/**
* 跨域流程
* 1,浏览器发送遇检请求(OPTIONS)
* 2,服务器响应允许跨域返回给浏览器,主要是给响应里添加如下响应头
* 3,发送真实数据
* 4,相应数据
*/
//每个请求都手动添加跨域需要的字段太麻烦,因为好多请求都要配置跨域,所以配置一个拦截器(专门做跨域的corsWebFilter)
// 在所有请求进来以后放行,执行完了之后返回给浏览器之前给响应里面添加上如下跨域字段
UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedHeader("*"); //允许所有头进行跨域
corsConfiguration.addAllowedMethod("*"); //允许所有请求方式跨域(GET PUT等)
corsConfiguration.addAllowedOrigin("*"); //允许所有请求来源跨域
corsConfiguration.setAllowCredentials(true); //是否允许携带Cookies进行跨域
source.registerCorsConfiguration("/**",corsConfiguration); //任意路径都要进行跨域配置
return new CorsWebFilter(source);
}
}
参考文章与课程
https://segmentfault.com/a/1190000015597029
https://www.cnblogs.com/zixian/p/9998131.html
https://www.bilibili.com/video/BV1np4y1C7Yf?p=46