跨域简介
跨域请求就是指:当前发起请求的域与该请求指向的资源所在的域不一样。这里的域指的是这样的一个概念:我们认为若协议 + 域名 + 端口号均相同,那么就是同域。
举个例子:假如一个域名为aaa.cn的网站,它发起一个资源路径为aaa.cn/books/getBookInfo的 Ajax 请求,那么这个请求是同域的,因为资源路径的协议、域名以及端口号与当前域一致(例子中协议名默认为http,端口号默认为80)。但是,如果发起一个资源路径为bbb.com/pay/purchase的 Ajax 请求,那么这个请求就是跨域请求,因为域不一致,与此同时由于安全问题,这种请求会受到同源策略限制。
演示一下,创建index.html,发送ajax测试跨域,代码如下所示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="./js/jquery/jquery-1.10.2.min.js"></script>
<script>
function sendAjax() {
$.ajax({
method: 'GET',
url: "http://localhost:9001/payment/123",
contentType: 'application/json; charset=UTF-8',
success: function(o) {
alert(o.id);
alert(o.message);
}
});
}
</script>
</head>
<body>
<button onclick="sendAjax();" >send ajax</button>
</body>
</html>
结果如图所示
通过上述index.html,发送请求,因为浏览器同源策略,就会出现跨域访问问题。
方法1----@CrossOrigin
虽然在安全层面上同源限制是必要的,但有时同源策略会对我们的合理用途造成影响,为了避免开发的应用受到限制,有多种方式可以绕开同源策略,常用的做法JSONP, CORS。可以使用@CrossOrigin,代码如下。
@RestController
@RequestMapping("/payment")
@CrossOrigin
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/{id}")
public ResponseEntity<Payment> payment(@PathVariable("id") Integer id) {
Payment payment = new Payment(id, "支付成功,服务端口=" + serverPort);
return ResponseEntity.ok(payment);
}
}
方法2----配置网关
让此跨域请求通过gatway网关访问(修改ajax请求中地址的端口号为网关的端口号),然后可以通过网关统一配置跨域访问,代码如下。
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
max-age: 3600
allowed-origin-patterns: "*" # spring boot2.4配置
# allowed-origins: "*"
allowed-headers: "*"
allow-credentials: true
allowed-methods:
- GET
- POST
- DELETE
- PUT
- OPTION
再次发送请求
请求成功