二十四 前后端分离应用的跨域接口调用
二十四 前后端分离应用的跨域接口调用
hiriki设计和实现运营后台的接口,以及在前后端分离项目中如何处理跨域接口访问的问题。
设计
在使用前后端分离的方式构建运营后台应用系统以后,会遇到一个非常常见的问题,就是跨域访问。那么什么是跨域访问呢?
跨域访问是指当一个网页从一个域名(或端口)请求另一个域名(或端口)的资源时,由于浏览器的同源策略限制,请求会被拒绝。跨域访问是一种常见的安全限制,用于防止网页在不受信任的域中访问敏感信息。
实现
【infrastructure层】OperationRequest
1 | package cn.ray.gateway.center.infrastructure.common; |
【infrastructure层】OperationResult
1 | package cn.ray.gateway.center.infrastructure.common; |
【infrastructure层】DataOperationManageRepository
1 | package cn.ray.gateway.center.infrastructure.repository; |
【domain层】DataOperationManageService
1 | package cn.ray.gateway.center.domain.operation.service; |
【interfaces层】DataOperationManage
1 | package cn.ray.gateway.center.interfaces; |
测试
前端页面
网关分组
算力节点
网关映射(分配)
应用服务
应用接口
接口方法
后台日志
1 | 2023-06-01 19:32:41.849 INFO 1693 --- [p-nio-80-exec-1] c.r.g.c.interfaces.DataOperationManage : 查询网关服务数据开始 groupId: page:1 limit:10 |
思考
跨域的几种解决方案
Java 可以通过以下几种方式解决跨域问题:
使用 CORS(Cross-Origin Resource Sharing 跨域资源共享):CORS 是一种机制,它使用额外的 HTTP 头来告诉浏览器,哪些源被允许访问该资源。在 Java 中,可以通过配置 Filter 或 Interceptor 来实现 CORS。
在 Java 中,可以通过配置 Filter 或 Interceptor 来实现 CORS。下面是一个使用 Filter 的示例:
1 |
|
在上面的示例中,我们定义了一个名为
CorsFilter
的 Filter,并使用@WebFilter
注解标记它。在doFilter
方法中,我们设置了允许的域名、请求方法、请求头字段、响应头字段、发送凭据和缓存时间,并将这些信息设置到响应头中。如果请求方法为 OPTIONS,则直接返回,否则调用chain.doFilter
方法继续处理请求。@WebFilter 是 Java Servlet 3.0 规范中的一种注解,用于定义过滤器。过滤器是一种可以在请求到达 Servlet 之前或响应离开 Servlet 之后对请求和响应进行预处理的组件。@WebFilter 注解可以用于指定需要拦截的 URL 模式、拦截器执行的顺序、拦截器的名称等信息。
通过使用 @WebFilter 注解,可以方便地创建一个过滤器,并将其应用到指定的 URL 上,以实现对请求和响应的处理和过滤。例如,可以使用 @WebFilter 注解来实现跨域请求的处理,将需要的响应头信息添加到响应中,以允许跨域请求。
需要注意的是,以上示例中的配置仅适用于单个域名,如果需要允许多个域名访问,则需要使用逗号分隔它们,并将其设置到
Access-Control-Allow-Origin
头中。另外,如果需要动态获取允许的域名,也可以在代码中进行配置。
使用 JSONP(JSON with Padding):JSONP 是一种跨域请求的解决方案,它利用了浏览器允许跨域请求加载 JavaScript 文件的特性。在 Java 中,可以通过返回 JSONP 格式的数据来实现跨域请求。
JSONP(JSON with Padding)是一种跨域请求的解决方案,它的原理是通过动态创建
<script>
标签,以 GET 方式向跨域的服务器发送请求,服务器返回一段 JavaScript 代码,该代码会被自动执行,从而实现跨域请求。具体实现步骤如下:
- 在客户端页面中定义一个回调函数,该函数用于接收服务器返回的数据。
- 使用动态创建
<script>
标签的方式,向跨域的服务器发送 GET 请求,请求的 URL 中包含回调函数的名称和其他参数。 - 服务器接收到请求后,将需要返回的数据包装成一个 JavaScript 函数调用的形式,该函数调用的名称就是客户端定义的回调函数名称,将包装好的数据返回给客户端。
- 客户端接收到服务器返回的数据后,自动执行回调函数,从而实现跨域请求。
需要注意的是,JSONP 只支持 GET 请求,并且返回的数据必须是 JSON 格式,否则会出现语法错误。此外,由于 JSONP 是通过动态创建
<script>
标签实现的,因此存在一定的安全风险,容易受到 XSS 攻击。因此,在使用 JSONP 时需要注意安全问题。
- 使用代理服务器:在 Java 中,可以通过配置代理服务器来实现跨域请求。代理服务器是一个位于客户端和服务器之间的中间层,它可以将客户端的请求转发给服务器,并将服务器的响应返回给客户端,从而实现跨域请求。
使用 WebSocket:WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它可以实现跨域通信。在 Java 中,可以使用 Spring WebSocket 框架来实现 WebSocket。
@CrossOrigin 是 Spring 框架提供的一个注解,用于处理跨域请求。它的原理是通过在响应头中添加 Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers 等字段,告诉浏览器该请求允许跨域访问。
当客户端发起跨域请求时,浏览器会自动发起 OPTIONS 请求,向服务器查询该请求是否允许跨域访问,该请求称为预检请求。服务器接收到预检请求后,会在响应头中添加 Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers 等字段,告诉浏览器该请求允许跨域访问。如果服务器返回的响应头中没有包含这些字段,浏览器会阻止该请求,从而防止跨域攻击。
使用 @CrossOrigin 注解可以简化配置跨域请求的过程,只需要在控制器方法上添加该注解,并指定需要允许跨域访问的域名、请求方法、请求头字段等信息即可。Spring 框架会自动处理跨域请求,并在响应头中添加相应的字段,从而允许跨域访问。
- 使用服务器端框架或库,例如 Spring 或 Apache Shiro,提供跨域访问支持。