springboot解决跨域

本地模拟跨域请求以及结果分析

  1. 写一个前端HTML页面放于idea(idea可充当静态web服务器)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CORS跨域</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<div style="text-align:center;margin-top: 100px;font-size: 60px;color: brown;cursor: pointer;">
<span onclick="sendAjaxReq()">发送Ajax请求</span>
</div>
<script type="text/javascript">
function sendAjaxReq() {
$.ajax({
type: "GET",
url: "http://localhost:8080/test/cors",
success: function (message) {
console.log("成功!" + message);
},
error: function (a, b, c) {
console.log("失败!" + a.statusText);
}
});
}
</script>
</body>
</html>
  1. 写一个控制器Controller处理页面发送的ajax请求
1
2
3
4
5
6
7
8
9
10
11
12
/**
* @author cuishiying
* @date 2021-01-22
*/
@RestController
public class CorsController {

@GetMapping("/test/cors")
public Object testCors() {
return "hello cors";
}
}
  1. 利用idea的web服务器能力运行html页面, 地址为: http://localhost:63342/cors-demo/static/index.html

请注意这个页面的访问地址的是 http://localhost:63342/cors-demo/static/index.html,而点击这个"发送Ajax请求"按钮要发送的地址是 http://localhost:8080/test/cors,两者端口号不一样说明是不同的域,因此此ajax请求它必定属于跨域请求(CORS请求)

  1. 点击发送按钮,查看控制台的结果
1
2
Access to XMLHttpRequest at 'http://localhost:8080/test/cors' from origin 'http://localhost:63342' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
失败!error
  1. 配置跨域, 再次访问 http://localhost:63342/cors-demo/static/index.html, 控制台输出 成功!hello cors
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* @author cuishiying
* @date 2021-01-22
*/
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}

@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}

生产案例

生成遇到1个上述配置没生效的情况, 后来发现是认证过滤器优先级比跨域过滤器优先级高, 导致在认证阶段直接返回了跨域, 调整优先级即可解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
* 版权所有 (c) 2024 idea360.cn。保留所有权利。
* 作者:cuishiying
* 网站:idea360.cn
* 微信公众号:当我遇上你
* 邮箱:idea360@foxmail.com
*/

package cn.idea360.cps.configuration;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
* @author cuishiying
*/
@Configuration
public class CorsConfig {

@Bean
public FilterRegistrationBean<CorsFilter> corsFilterRegistrationBean() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOriginPattern(CorsConfiguration.ALL);
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
corsConfiguration.setAllowCredentials(true);

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
CorsFilter corsFilter = new CorsFilter(source);

FilterRegistrationBean<CorsFilter> filterRegistrationBean = new FilterRegistrationBean<>(corsFilter);
filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);

return filterRegistrationBean;
}

}

测试页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>跨域请求测试</title>
</head>
<body>
<h1>跨域请求测试</h1>

<!-- 输入框用于输入测试URL -->
<input type="text" id="urlInput" placeholder="请输入测试URL" style="width: 300px;">
<button id="fetchData">发送跨域请求</button>
<p id="response"></p>

<script>
document.getElementById('fetchData').addEventListener('click', function() {
const url = document.getElementById('urlInput').value;

if (!url) {
document.getElementById('response').innerText = '请输入一个有效的URL';
return;
}

fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('网络响应失败,状态码:' + response.status);
}
return response.json();
})
.then(data => {
document.getElementById('response').innerText = JSON.stringify(data, null, 2);
})
.catch(error => {
document.getElementById('response').innerText = '请求失败: ' + error;
});
});
</script>
</body>
</html>

最后

本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。