跨域(Cross-Origin)指的是在网络环境中,当一个网页的文档或脚本(例如JavaScript)尝试获取来自不同域名、不同协议或不同端口的资源时,就会发生跨域请求。同源策略是一种浏览器的安全策略,它限制了不同源之间的互相操作。
同源策略要求两个网址具有相同的协议(如HTTP或HTTPS)、主机(域名)和端口号,即使两个网址在不同的子域名下,同源策略也会将其视为不同源,禁止跨域操作。
跨域请求可能会涉及不同域之间的数据交换,例如在前端网页中通过Ajax请求获取来自其他域的数据。由于同源策略的限制,浏览器会阻止跨域请求,并在控制台中显示错误信息,除非在服务器端进行相应的配置来允许跨域请求。
为了实现跨域请求,可以采取一些常见的解决方案,如JSONP(利用<script>
标签的src属性不受同源策略限制)、CORS(跨域资源共享,通过设置响应头来允许跨域请求)、代理服务器等。这些解决方案允许在一定程度上实现跨域请求,但需要根据具体情况选择合适的方法来解决跨域问题。
1.跨域请求JSONP
前端:
$.ajax({
url:"http://localhost:8080/cors/jsonp/1",
dataType:"jsonp",
//jsonp:"a" 不指定默认为callback
//jsonpCallback:"c" 不指定自动生成
type:"GET",
success:function(result){
alert(result,data)
}
})
后端:
@RestController
@RequestMapping("/cors")
public class CorsController {
@GetMapping("/json/{id}")
public JSONPObject getUser(@PathVariable Integer id,String callbacker){
//第一个参数是前端提交的callbacker,第二个参数是你要给前端提交的数据
return new JSONPObject(callbacker,"jsonp");
}
}
优点:
-
JSONP的优点就是因为比较老,可以兼容各种浏览器,无兼容问题
缺点:
-
只支持get请求,而且存在安全问题
-
技术发展至今,JSONP这种前后端耦合的方式基本已被代替
原理:前端给后端发送ajax请求,在没有被指定JSONP的情况下,前端会给后端发送一个自定义生成的callback,然后后端接收并将发送过来的前端的参数callback和当前需要给前端的数据发送给前端,这当前端收到后端传过来的数据之后,就说明前端认为你是一个安全的跨域请求,然后就可以正常的去访问了(握手)
2.跨域请求CORS
前端:
不需要做任何的跨域操作,直接向后端发送请求
$.ajax({
url:"http://localhost:8080/cors/jsonp/1",
type:"GET",
success:function(result){
alert(result,data)
}
})
后端:
针对某一个接口进行跨域
@RestController
@RequestMapping("/cors")
public class CorsController {
@GetMapping("{id}")
@CrossOrigin("http://localhost:8081")
public String getUser(@PathVariable Integer id){
return "Stirng";//返回给前端提供的数据
}
}
批量的支持一批接口来支持跨域
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/user/*")//映射服务器中的哪些接口可以支持跨域
.allowedOrigins("http://localhost:8080")//配置哪些来源有权限进行跨域
.allowedMethods("GET","POST","DELETE","PUT");//配置运行跨域访问的方式
}
}
全部接口支持跨域
@Configuration
public class MyCorsFilter {
@Bean
public CorsFilter corsFilter(){
//创建CORS配置对象
CorsConfiguration config=new CorsConfiguration();
//支持域
config.addAllowedOrigin("*");
//是否发送Cookie
config.setAllowCredentials(true);
//支持请求的方式
config.addAllowedMethod("*");
//添加地址映射
UrlBasedCorsConfigurationSource corsConfigurationSource=new UrlBasedCorsConfigurationSource();
corsConfigurationSource.registerCorsConfiguration("/**",config);
//返回CorsFilter对象
return new CorsFilter(corsConfigurationSource);
}
}
1.CORS从具体的代码实现上来说比较方便,前端几乎不需要写任何的代码就可以支持,主要是靠服务端进行配置
2.CORS需要浏览器和服务器同时支持,目前的所有浏览器都支持该功能
3.浏览器一旦发现Ajax请求跨域,就会自动的添加一些附加的头信息,有时还会多出一次附加的请求用户不会有感觉
3.跨域请求Nginx
前端:
$.ajax({
url:"http://localhost:8081/cors/1",
type:"GET",
success:function(result){
alert(result,data)
}
})
Nginx配置更改:
server {
# 监听8081端口
listen 8081;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
#如果前端发送的端口中包含/cors/路径直接转接给http://localhost:8080/user/
location /cors/{
proxy_pass http://localhost:8080/user/;
}
}
这种配置前后端都不用进行任何的跨域操作,只需要在nginx中进行配置,当nginx检测到前端的请求路径中包含cors,就自动的将这个请求转发给http://localhost:8080/user/