统一解决跨域请求
跨域问题简介
跨域请求就是指:当前发起请求的域与该请求指向的资源所在的域不⼀样。这⾥的域指的是这样的⼀个概念:我们认为若协议 + 域名 + 端⼝号均相同,那么就是同域。举个例⼦:假如⼀个域名为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.js">
</script>
<script>
function sendAjax() {
$.ajax({
method: 'GET',
url: "http://127.0.0.1:9005/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,发送请求,因为浏览器同源策略,就会出现跨域访问问题。
虽然在安全层⾯上同源限制是必要的,但有时同源策略会对我们的合理⽤途造成影响,为了避免开
发的应⽤受到限制,有多种⽅式可以绕开同源策略,常⽤的做法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);
}
}
使用@CrossOrigin这种方式存在一些弊端,例如我们会有很多的微服务,如果每个微服务都要加上@CrossOrigin注解,工作量会比较大,所以这里推荐以下解决方式,也就是在微服务网关中统一配置跨域访问,代码如下:
需要在yml中配置
server:
port: 9005
spring:
application:
name: api-gateway
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origin-patterns: "*" # spring boot2.4配置
# allowed-origins: "*"
allowed-headers: "*"
allow-credentials: true
allowed-methods:
- GET
- POST
- DELETE
- PUT
- OPTION
通过以上配置便可以实现微服务的跨域请求