Java跨域问题的几种后端解决方式举例详解

 更新时间:2023年11月07日 09:38:19   作者:earlytrain9653  
跨域,是指浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制,这篇文章主要给大家介绍了关于Java跨域问题的几种后端解决方式的相关资料,需要的朋友可以参考下

一、什么是跨域

跨域指的是:浏览器不能执行其他网站的脚本,从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。跨域是由浏览器的同源策略造成的,是浏览器施加的安全限制。a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的。

二、常见跨域举例

当前页面URL被请求页面URL是否跨域原因
http://www.test.com/http://www.test.com/index.html同源 (协议、域名、端口号相同)
http://www.test.com/https://www.test.com/index.html跨域协议不同 (http/https)
http://www.test.com/http://www.baidu.com/跨域域名不同 (test/baidu)
http://www.test.com/http://blog.test.com/跨域域名不同 (www/blog)
http://www.test.com:8080/http://www.test.com:7001/跨域端口号不同 (8080/7001)

三、Java后端解决方式

1、实现 WebMvcConfigurer

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")// 拦截所有的请求
            .allowedOrigins("*")// 可跨域的域名,*为所有
            .allowCredentials(true)
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允许跨域的方法,可以单独配置
            .maxAge(3600);
    }
}

2、实现 HandlerInterceptor

创建一个类实现 HandlerInterceptor 接口,并在 preHandle 方法中设置响应头以实现跨域。

@Component
public class CorsInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "http://example.com");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        return true;
    }
    // ...
}
```

这将允许来自 http://example.com 的跨域请求访问应用程序中的 API。

3、使用Filter

创建一个类实现 javax.servlet.Filter 接口,并在 doFilter 方法中设置响应头以实现跨域。

@WebFilter
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "http://example.com");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(req, res);
    }
    // ...
}
````

这将允许来自 http://example.com 的跨域请求访问应用程序中的 API。

注意:使用 Filter 实现跨域时,Filter 会拦截所有请求,而不仅仅是跨域请求。因此,在设置响应头时需要谨慎,避免影响其他请求的正常处理。如果需要更细粒度的控制,可以考虑使用 @CrossOrigin 注解或拦截器来实现。

4、使用 @CrossOrigin 注解来实现

在使用 Spring Boot 实现跨域时,可以使用 Spring 提供的 @CrossOrigin 注解来配置跨域访问。具体实现步骤如下:

(1)在需要实现跨域的 Controller 类或方法上添加 @CrossOrigin 注解。例如:

@CrossOrigin(origins = "http://example.com")
@RestController
public class MyController {
    // ...
}
```
这将允许来自 http://example.com 的跨域请求访问 MyController 中的方法。

(2)如果需要允许多个域名访问,可以将 origins 参数设置为包含所有允许访问的域名的数组。例如:

@CrossOrigin(origins = {"http://example1.com", "http://example2.com"})
@RestController
public class MyController {
    // ...
}
```

(3)如果需要允许跨域的 HTTP 方法不止 GET 和 POST,可以使用 methods 参数指定允许的方法列表。例如:

@CrossOrigin(origins = "http://example.com", methods = {RequestMethod.GET, RequestMethod.POST})
@RestController
public class MyController {
    // ...
}
```

(4)如果需要允许跨域的请求头不止 Content-Type,可以使用 allowedHeaders 参数指定允许的请求头列表。例如:

@CrossOrigin(origins = "http://example.com", allowedHeaders = {"Content-Type", "Authorization"})
@RestController
public class MyController {
    // ...
}
```

(5)如果需要允许发送身份验证信息,可以使用 allowCredentials 参数将其设置为 true。例如:

@CrossOrigin(origins = "http://example.com", allowCredentials = "true")
@RestController
public class MyController {
    // ...
}
```

5、在响应头中添加 Access-Control-Allow-Origin 等字段

(1)在响应头中添加 Access-Control-Allow-Origin 字段,允许特定的域名访问。例如,以下代码将允许 http://example.com 的域名访问 API:

response.setHeader("Access-Control-Allow-Origin", "http://example.com");
```
如果希望允许所有域名访问 API,可以将值设置为 *:

(2)如果需要允许多个域名访问 API,可以在响应头中添加 Access-Control-Allow-Origin 字段,并将其设置为包含所有允许访问的域名的列表。例如:

response.setHeader("Access-Control-Allow-Origin", "http://example1.com, http://example2.com");
```

(3)如果需要允许跨域的 HTTP 方法不止 GET 和 POST,可以在响应头中添加 Access-Control-Allow-Methods 字段,指定允许的方法列表。例如:

response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
```

(4)如果需要允许跨域的请求头不止 Content-Type,可以在响应头中添加 Access-Control-Allow-Headers 字段,指定允许的请求头列表。例如:

response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
```

(5)如果使用了带有身份验证信息的请求,例如带有 Cookie 的请求,那么需要在响应头中添加 Access-Control-Allow-Credentials 字段,并将其设置为 true,表示允许发送身份验证信息。例如:

response.setHeader("Access-Control-Allow-Credentials", "true");
```
最后,需要将这些响应头添加到每个需要跨域访问的 API 的响应中。

6、使用 Nginx 配置

location / {
   add_header Access-Control-Allow-Origin *;
   add_header Access-Control-Allow-Headers X-Requested-With;
   add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;

   if ($request_method = 'OPTIONS') {
     return 204;
   }
}

如果使用了带有身份验证信息的请求,例如带有 Cookie 的请求,那么需要将 Access-Control-Allow-Credentials 字段设置为 true,表示允许发送身份验证信息。例如:

add_header 'Access-Control-Allow-Credentials' 'true';

如果在 Nginx 的 upstream 中使用了负载均衡,需要在负载均衡的服务器块中添加以上配置。如果使用了反向代理,也需要在反向代理的服务器块中添加以上配置。

7、配置 Gateway 的路由

- id: my_route
  uri: http://localhost:8080
  predicates:
    - Path=/api/**
  filters:
    - RewritePath=/api/(?<segment>.*), /$\{segment}
    - AddResponseHeader=Access-Control-Allow-Origin:http://example.com
    - AddResponseHeader=Access-Control-Allow-Methods:GET, POST, PUT, DELETE
    - AddResponseHeader=Access-Control-Allow-Headers:Content-Type, Authorization
    - AddResponseHeader=Access-Control-Allow-Credentials:true
`````

这将允许来自 http://example.com 的跨域请求访问 Gateway 中的 API。

如果使用了带有身份验证信息的请求,例如带有 Cookie 的请求,那么需要将 Access-Control-Allow-Credentials 字段设置为 true,表示允许发送身份验证信息。例如:

- AddResponseHeader=Access-Control-Allow-Credentials:true
`````
最后,需要将这些配置添加到每个需要跨域访问的 API 的路由配置中。
需要注意的是,如果在 Gateway 的路由中使用了负载均衡,需要在负载均衡的路由配置中添加以上配置。如果使用了反向代理,也需要在反向代理的路由配置中添加以上配置。

总结 

到此这篇关于Java跨域问题的几种后端解决方式的文章就介绍到这了,更多相关Java跨域问题后端解决内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解读java try catch 异常后还会继续执行吗

    解读java try catch 异常后还会继续执行吗

    这篇文章主要介绍了解读java try catch 异常后还会不会继续执行问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • SpringBoot如何优雅的处理全局异常

    SpringBoot如何优雅的处理全局异常

    这篇文章主要给大家介绍了关于SpringBoot如何优雅的处理全局异常的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用SpringBoot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • Java操作minio删除文件夹及其文件方法(MinIO基本使用)

    Java操作minio删除文件夹及其文件方法(MinIO基本使用)

    MinIO是一个高性能、无限扩展的开源对象存储服务器,它以对象的形式存储数据,并兼容Amazon S3接口,它适用于大规模数据存储、大数据分析、文件共享和备份等应用场景,这篇文章主要介绍了java操作minio删除文件夹及其文件方法,需要的朋友可以参考下
    2024-02-02
  • JAVA数字千分位和小数点的现实代码(处理金额问题)

    JAVA数字千分位和小数点的现实代码(处理金额问题)

    这篇文章主要介绍了JAVA数字千分位和小数点的现实代码(处理金额问题),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Maven仓库分类的优先级

    Maven仓库分类的优先级

    本文主要介绍了Maven仓库分类的优先级,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • IDEA如何加载resources文件夹下文件相对路径

    IDEA如何加载resources文件夹下文件相对路径

    这篇文章主要介绍了IDEA如何加载resources文件夹下文件相对路径问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 在AOP中Spring生成代理类的两种方式

    在AOP中Spring生成代理类的两种方式

    今天小编就为大家分享一篇关于在AOP中Spring生成代理类的两种方式,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Spring:@Async注解和AsyncResult与CompletableFuture使用问题

    Spring:@Async注解和AsyncResult与CompletableFuture使用问题

    这篇文章主要介绍了Spring:@Async注解和AsyncResult与CompletableFuture使用问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • JavaWeb利用邮箱帮用户找回密码

    JavaWeb利用邮箱帮用户找回密码

    这篇文章主要为大家详细介绍了JavaWeb利用邮箱帮用户找回密码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • Java基本语法小白入门级

    Java基本语法小白入门级

    Java基本语法就是指java中的规则,也是一种语言规则,规范,同时也能让您在后面的学习中避免不必要的一些错误和麻烦,是您学好java必修的第一门课程
    2023-05-05

最新评论