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 跨域的资料请关注我们其它相关文章!

(0)

相关推荐

  • java web服务器实现跨域访问

    一.CORS概述 跨源资源共享标准通过新增一系列 HTTP 头,让服务器能声明那些来源可以通过浏览器访问该服务器上的各类资源(包括CSS.图片.JavaScript 脚本以及其它类资源).另外,对那些会对服务器数据造成破坏性影响的 HTTP 请求方法(特别是 GET 以外的 HTTP 方法,或者搭配某些MIME类型的POST请求),标准强烈要求浏览器必须先以 OPTIONS 请求方式发送一个预请求(preflight request),从而获知服务器端对跨源请求所支持 HTTP 方法.在确认服务

  • Java Spring boot 2.0 跨域问题的解决

    跨域 一个资源会发起一个跨域HTTP请求(Cross-site HTTP request), 当它请求的一个资源是从一个与它本身提供的第一个资源的不同的域名时 . 比如说,域名A(http://domaina.example)的某 Web 应用程序中通过标签引入了域名B(http://domainb.foo)站点的某图片资源(http://domainb.foo/image.jpg),域名A的那 Web 应用就会导致浏览器发起一个跨站 HTTP 请求.在当今的 Web 开发中,使用跨站 HTTP

  • Java服务器端跨域问题解决方案

    这篇文章主要介绍了java服务器端跨域问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 现在很多开发的 API 都支持 ajax 直接请求,这样就会导致跨域的问题,解决跨域的问题一方面可以从前端,另一方面就是服务器端. 一.Controller类名上方添加@CrossOrigin 注解通过此方式注解则Controller中的所有通过@RequestMapping注解的方法都可以进行跨域请求. 代码如下: @CrossOrigin()

  • java解决请求跨域的两种方法

    java解决请求跨域问题,有以下两种写法 1.使用拦截器,实现javax.servlet.Filter接口 import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.S

  • JAVA通过Filter实现允许服务跨域请求的方法

    概念 在 HTML 中,<a>, <form>, <img>, <script>, <iframe>, <link> 等标签以及 Ajax 都可以指向一个资源地址, 而所谓的跨域请求就是指:当前发起请求的域与该请求指向的资源所在的域不一样. 这里的域指的是这样的一个概念:我们认为若协议 + 域名 + 端口号均相同,那么就是同域即我们常说的浏览器请求的同源策略. Jsonp 在前后端分离的项目中,会经常遇到需要跨域请求的问题.跨域请求有

  • vue+Java后端进行调试时解决跨域问题的方式

    今天在开发过程中遇到一个问题,拿到了一套vue代码,计划对这套代码的部分样式进行调整,Java后端代码已经写好并且部署到了线上.这时命令行运行vue项目时访问会受限,取不下数据来,遇到了跨域访问失败的问题,这时可以怎么做呢? 首先,要了解什么叫跨域访问? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制. 所谓同源是指,域名,协议,端口均相同,举个例子: http://www.123.com/index.html 调用 http

  • Java开发中解决Js的跨域问题过程解析

    这篇文章主要介绍了Java开发中解决Js的跨域问题过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 主流方法有JSONP和CORS两种,这里记一下后者的方式,理论基础就是在请求的时候在http请求头中添加如下属性: //指定允许其他域名访问 Access-Control-Allow-Origin:http://localhost:8989 如果后端用Java开发,在返回请求中可以添加如下属性 1.在跨域问题中,如果不操作cookie,只需

  • Java使用Ajax实现跨域上传图片功能

    说明 : 图片服务器是用Nginx搭建的,用的是PHP语言 这个功能 需要 用到两个js文件: jquery.js和jQuery.form.js <script type="text/JavaScript" src="js/jquery.js"></script> <script type="text/javascript" src="js/jquery.form.js"></scri

  • 详解java 中Spring jsonp 跨域请求的实例

    详解java 中Spring jsonp 跨域请求的实例 jsonp介绍 JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏览器的跨域数据访问的问题.由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外.利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSO

  • java使用webuploader实现跨域上传详解

    前言 项目中使用webuploader进行文件上传,需要用到跨域,查看webuploader的issues发现是支持上传的,但是他们写的回复都是不清不白的,有点迷糊:想了半天才知道咋回事,也可能是我比较笨,再次记录下java中详细的处理. webuploader进行上传,会执行2个请求:一个option请求,一个post(根据你的webuploader的配置method 值决定),需要在option请求中对响应头进行处理,post响应头也进行响应的处理. 以servlet为例: @WebServ

随机推荐