Java 跨域问题的处理方式

 更新时间:2020年11月19日 09:58:49   作者:rxliuli   
这篇文章主要介绍了Java 跨域问题的处理方式,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下

问题

在页面上要使用 Ajax 请求去获取另外一个服务的数据,由于浏览器的 同源策略,所以直接请求会得到一个 Error。

Failed to load https://www.baidu.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

大概就是这样的一个错误,关键词是 Access-Control-Allow-Origin,一般出现这个都是跨域问题。

解决方案

解决跨域问题的方式有很多,但这里之说 Cors 的方案。

在后台添加一个 Filter 过滤器

/**
 * 使用自定义的 Filter 拦截器实现跨域请求、
 * 适用于所有的 Java Web 项目并且不局限于某个框架
 * 注:此处的 @Component 仅为让 Spring 知道这个 Bean, 不然拦截器不会加载
 *
 * @author rxliuli
 */
public class CustomCorsFilterConfig implements Filter {
  @Override
  public void init(FilterConfig filterConfig) {
  }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    //允许所有来源
    String allowOrigin = "*";
    //允许以下请求方法
    String allowMethods = "GET,POST,PUT,DELETE,OPTIONS";
    //允许以下请求头
    String allowHeaders = "Content-Type,X-Token,Authorization";
    //允许有认证信息(cookie)
    String allowCredentials = "true";

    String origin = request.getHeader("Origin");
    //此处是为了兼容需要认证信息(cookie)的时候不能设置为 * 的问题
    response.setHeader("Access-Control-Allow-Origin", origin == null ? allowOrigin : origin);
    response.setHeader("Access-Control-Allow-Methods", allowMethods);
    response.setHeader("Access-Control-Allow-Credentials", allowCredentials);
    response.setHeader("Access-Control-Allow-Headers", allowHeaders);

    //处理 OPTIONS 的请求
    if ("OPTIONS".equals(request.getMethod())) {
      response.setStatus(HttpServletResponse.SC_OK);
      return;
    }
    filterChain.doFilter(request, response);
  }

  @Override
  public void destroy() {
  }
}

在 web.xml 文件中添加拦截器配置(注:如果可能就配置成第一个 Filter)

<!--cors 跨域访问-->
<filter>
 <filter-name>customCorsFilterConfig</filter-name>
 <filter-class>CustomCorsFilterConfig</filter-class>
</filter>
<filter-mapping>
 <filter-name>customCorsFilterConfig</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

Spring Web 的解决方案

配置一个每次请求都过滤一次的 Filter 就好了

@Configuration
public class CorsConfig {
  @Bean
  public OncePerRequestFilter corsFilter() {
    return new OncePerRequestFilter() {
      @Override
      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //允许所有来源
        String allowOrigin = "*";
        //允许以下请求方法
        String allowMethods = "GET,POST,PUT,DELETE,OPTIONS";
        //允许以下请求头
        String allowHeaders = "Content-Type,X-Token,Authorization";
        //允许有认证信息(cookie)
        String allowCredentials = "true";

        String origin = request.getHeader("Origin");
        //此处是为了兼容需要认证信息(cookie)的时候不能设置为 * 的问题
        response.setHeader("Access-Control-Allow-Origin", origin == null ? allowOrigin : origin);
        response.setHeader("Access-Control-Allow-Methods", allowMethods);
        response.setHeader("Access-Control-Allow-Credentials", allowCredentials);
        response.setHeader("Access-Control-Allow-Headers", allowHeaders);

        //处理 OPTIONS 的请求
        if ("OPTIONS".equals(request.getMethod())) {
          response.setStatus(HttpServletResponse.SC_OK);
          return;
        }
        filterChain.doFilter(request, response);
      }
    };
  }
}

使用示例

下面是一些简单的使用 fetch 进行跨域请求的示例:

  • 简单 fetch 请求,和正常使用 fetch 并无区别
fetch(url)
 .then(res => res.json())
 .then(json => console.log(json))
  • 表单请求
var fd = new FormData()
fd.append('username', 'rx')
fd.append('password', 'rx')

fetch(url, {
 method: 'POST',
 body: fd,
})
 .then(res => res.json())
 .then(json => console.log(json))
  • 需要认证的请求
fetch(url, {
 /**
  * 关键就在这里,代表用户是否应该在跨域的情况下发送 cookies 和 HTTP Basic authentication 等验信息以及服务端能否返回 Set-Cookie(服务端 Session 需要使用这个向 cookie 中设置 sessionId)。
  * 包含三个可选值:omit(从不发送), same-origin(同源才发送), include(总会发送)
  * 参考链接:<https://developer.mozilla.org/zh-CN/docs/Web/API/Request/credentials>
  */
 credentials: 'include',
})
 .then(res => res.json())
 .then(json => console.log(json))

注:如果想要服务端返回 Set-Cookie(SessionId 也需要通过这个响应属性去设置) 就必须设置这个请求参数!

那么,之后在前端跨域请求的时候就可以愉快地玩耍啦(v^_^)v

以上就是Java 跨域问题的处理方式的详细内容,更多关于Java 跨域的资料请关注脚本之家其它相关文章!

相关文章

  • Java源码解析阻塞队列ArrayBlockingQueue功能简介

    Java源码解析阻塞队列ArrayBlockingQueue功能简介

    今天小编就为大家分享一篇关于Java源码解析阻塞队列ArrayBlockingQueue功能简介,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Spring底层原理深入分析

    Spring底层原理深入分析

    Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能
    2022-07-07
  • 浅谈JAVA 类加载器

    浅谈JAVA 类加载器

    这篇文章主要介绍了JAVA 类加载器的的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • 全面解析JPA 仓库repository中的findAll()方法

    全面解析JPA 仓库repository中的findAll()方法

    这篇文章主要介绍了全面解析JPA 仓库repository中的findAll()方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 浅谈spring boot 1.5.4 异常控制

    浅谈spring boot 1.5.4 异常控制

    下面小编就为大家带来一篇浅谈spring boot 1.5.4 异常控制。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Java中的@interface注解使用详解

    Java中的@interface注解使用详解

    这篇文章主要介绍了Java中的@interface注解使用详解,注解@interface不是接口是注解类,在jdk1.5之后加入的功能,使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,需要的朋友可以参考下
    2023-12-12
  • idea2020.3.3集成maven及遇到的坑(推荐)

    idea2020.3.3集成maven及遇到的坑(推荐)

    这篇文章主要介绍了idea2020.3.3集成maven的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • java:java.lang.ExceptionInInitializerError报错解决过程

    java:java.lang.ExceptionInInitializerError报错解决过程

    这篇文章主要给大家介绍了关于java:java.lang.ExceptionInInitializerError报错的解决过程,java.lang.ExceptionInInitializerError 是一个异常,表示在初始化一个类的静态变量或静态块时发生了错误,需要的朋友可以参考下
    2023-10-10
  • 找出链表倒数第n个节点元素的二个方法

    找出链表倒数第n个节点元素的二个方法

    本文提供了找出链表倒数第n个节点元素的二个方法,其中一个方法是JAVA代码实现
    2013-11-11
  • Java零基础精通方法篇

    Java零基础精通方法篇

    方法,也称函数,如果想要重复一段或者多段代码块的使用,可以将这些代码封装成一个方法,方法具体表现为某种行为,使用方法可以提高代码的复用性
    2022-05-05

最新评论