Java实现CORS跨域请求的实现方法

问题

使用前后端分离模式开发项目时,往往会遇到这样一个问题 -- 无法跨域获取服务端数据

这是由于浏览器的同源策略导致的,目的是为了安全。在前后端分离开发模式备受青睐的今天,前端和后台项目往往会在不同的环境下进行开发,这时就会出现跨域请求数据的需求,目前的解决方案主要有以下几种:

JSONP、iframe、代理模式、CORS等等
前面几种方式在这里不讲,网上有很多资料。在这里我主要分享一下CORS这种解决方式,CORS即“跨域资源共享”,它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

使用 CORS 跨域的时候和普通的 ajax 过程是一样的,只是浏览器在发现这是一个跨域请求的时候会自动帮我们处理一些事情,所以说只要服务端提供支持,前端是不需要做额外的事情的。

实现

实现的大概思路是这样的,首先使用过滤器获取请求对象request的信息,比如Origin 字段(表示请求来自哪个源,包括协议、域名、端口),通过预先配置的参数判断请求是否合法,然后设置响应对象response的头信息,实现跨域资源请求。在介绍实现方式之前我们先来了解一下会用到的响应头信息。

响应头

Access-Control-Allow-Methods
用来列出浏览器的CORS请求允许使用的HTTP方法,如:GET、POST、PUT、DELETE、OPTIONS

Access-Control-Allow-Credentials
表示是否支持跨域Cookie

Access-Control-Allow-Headers
逗号分隔的字符串,表示服务器支持的所有头信息字段,如Content-Type以及自定义的字段

Access-Control-Expose-Headers
与“Access-Control-Allow-Headers”相反,表示不支持的头信息字段

Access-Control-Allow-Origin
允许跨域的请求源信息,包括协议、域名、端口,为*表示允许所有请求来源,并且只能设置一个请求源

下面介绍一下Java后台如何实现这种方式。

代码

由于最近在使用spring-boot,所以接下来以spring-boot为基础来实现。

首先创建一个CorsFilter过滤器,代码如下:

...
@WebFilter(filterName = "corsFilter", urlPatterns = "/*",
    initParams = {@WebInitParam(name = "allowOrigin", value = "*"),
        @WebInitParam(name = "allowMethods", value = "GET,POST,PUT,DELETE,OPTIONS"),
        @WebInitParam(name = "allowCredentials", value = "true"),
        @WebInitParam(name = "allowHeaders", value = "Content-Type,X-Token")})
public class CorsFilter implements Filter {

  private String allowOrigin;
  private String allowMethods;
  private String allowCredentials;
  private String allowHeaders;
  private String exposeHeaders;

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    allowOrigin = filterConfig.getInitParameter("allowOrigin");
    allowMethods = filterConfig.getInitParameter("allowMethods");
    allowCredentials = filterConfig.getInitParameter("allowCredentials");
    allowHeaders = filterConfig.getInitParameter("allowHeaders");
    exposeHeaders = filterConfig.getInitParameter("exposeHeaders");
  }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    if (!StringUtils.isEmpty(allowOrigin)) {
      if(allowOrigin.equals("*")){
        response.setHeader("Access-Control-Allow-Origin", allowOrigin);
      }else{
        List<String> allowOriginList = Arrays.asList(allowOrigin.split(","));
        if (allowOriginList != null && allowOriginList.size() > 0) {
          String currentOrigin = request.getHeader("Origin");
          if (allowOriginList.contains(currentOrigin)) {
            response.setHeader("Access-Control-Allow-Origin", currentOrigin);
          }
        }
      }
    }
    if (!StringUtils.isEmpty(allowMethods)) {
      response.setHeader("Access-Control-Allow-Methods", allowMethods);
    }
    if (!StringUtils.isEmpty(allowCredentials)) {
      response.setHeader("Access-Control-Allow-Credentials", allowCredentials);
    }
    if (!StringUtils.isEmpty(allowHeaders)) {
      response.setHeader("Access-Control-Allow-Headers", allowHeaders);
    }
    if (!StringUtils.isEmpty(exposeHeaders)) {
      response.setHeader("Access-Control-Expose-Headers", exposeHeaders);
    }
    filterChain.doFilter(servletRequest, servletResponse);
  }

  @Override
  public void destroy() {

  }
}

大功告成,现在前端就可以跨域获取后台的数据了,比其它方式容易得多,代码就不解释了,简单易懂,使用其它后台开发方式也一样,最终目的就是判断请求,设置响应头,前端什么事都不用做。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 使用CORS实现JavaWeb跨域请求问题的方法

    之前用jsonp 解决跨域问题,现在用CORS实现跨域请求解决java 跨域问题: 主要代码如下 package com.hy.fliter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.

  • Cors实现java后端完全跨域实例

    http://www.jb51.net/article/114838.htm这篇文章很详细的介绍了JS的跨域,给出的解决方案是springboot的方式,假如不用spring boot 或者 spring版本低于4.2就需要自己实现: 参考了spring boot的实现方式,并有所简化,代码如下: package com.lvluo.web.filter.CorsFilter; import java.io.IOException; import javax.servlet.Filter; im

  • Java利用cors实现跨域请求实例

    由于ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告 网站开发,在某些情况下需要用到跨域. 什么是跨域? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制. ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告. 常见解决跨域的方式 script标签 iframe

  • Javaweb使用cors完成跨域ajax数据交互

    跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制. ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告. cors 全称:Cross-Origin Resource Sharing 中文意思:跨域资源共享 它在维基百科上的定义是:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源.而

  • Java实现CORS跨域请求的实现方法

    问题 使用前后端分离模式开发项目时,往往会遇到这样一个问题 -- 无法跨域获取服务端数据 这是由于浏览器的同源策略导致的,目的是为了安全.在前后端分离开发模式备受青睐的今天,前端和后台项目往往会在不同的环境下进行开发,这时就会出现跨域请求数据的需求,目前的解决方案主要有以下几种: JSONP.iframe.代理模式.CORS等等 前面几种方式在这里不讲,网上有很多资料.在这里我主要分享一下CORS这种解决方式,CORS即"跨域资源共享",它允许浏览器向跨源服务器,发出XMLHttpRe

  • react中fetch之cors跨域请求的实现方法

    项目中使用了react,当中需要使用fetch来代替ajax. 由于react的create_react_app工具很方便,基本上开箱即用,经过创建项目,输入npm start命令后,便自动监听一个3000的端口,到此前端部分就绪. 具体参考:https://github.com/facebookincubator/create-react-app 后端部分我使用了phalcon. 由于前后端分离,为了方便,我尝试在nginx中使之同域(前端和后台api的顶级域名相同),但phalcon框架是单

  • Springboot处理CORS跨域请求的三种方法

    前言 Springboot跨域问题,是当前主流web开发人员都绕不开的难题.但我们首先要明确以下几点 跨域只存在于浏览器端,不存在于安卓/ios/Node.js/python/ java等其它环境 跨域请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了. 之所以会跨域,是因为受到了同源策略的限制,同源策略要求源相同才能正常进行通信,即协议.域名.端口号都完全一致. 浏览器出于安全的考虑,使用 XMLHttpRequest对象发起 HTTP请求时必须遵守同源策略,否则就是跨域的H

  • 使用SpringCloudApiGateway之支持Cors跨域请求

    问题背景 公司的项目需要前后端分离,vue+java,这时候就需要支持Cors跨域请求了.最近对zuul进行升级,假如说zuul是1.0的话,api gateway就是2.0的网关,支持ws等,基于NIO,各方面还是强大的. 解决方案 新建一个Configuration类即可 import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.gateway.dis

  • 跨域请求两种方法 jsonp和cors的实现

    在网站后台跨域访问另一服务器时,若被访问服务器未设置response['Access-Control-Allow-Origin'] = '*' 那么将无法获取. jsonp方法 伪造ajax提交请求 请求端 // 基于jsonp // 原理: ajax 不能直接跨域 . //向html中加入script标签 含有访问路径,script标签直接访问路径达到效果 $('.get_service2').click(function () { // 伪造ajax提交请求 $.ajax({ url:'ht

  • Springboot处理配置CORS跨域请求时碰到的坑

    最近开发过程中遇到了一个问题,之前没有太注意,这里记录一下.我用的SpringBoot版本是2.0.5,在跟前端联调的时候,有个请求因为用户权限不够就被拦截器拦截了,拦截器拦截之后打印日志然后response了一个错误返回了,但是前端Vue.js一直报如下跨域的错误,但是我是配置了跨域的. has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested res

  • vue 本地环境跨域请求proxyTable的方法

    主要在config->index.js中配置 proxyTable: { '/gameapi': { changeOrigin: true, // target: 'http://rap.id.cn/mockjs/20', mock地址 target: 'http://192.168.1.124',服务器地址 pathRewrite: { '^/gameapi': '/gameapi' }, secure:false } } 因此,发送请求时候url写为('/gameapi/gift-apply

  • Node.js设置CORS跨域请求中多域名白名单的方法

    CORS 说到CORS,相信前端儿都不陌生,这里我就不多说了,具体可以看看这篇文章. CORS,主要就是配置Response响应头中的 Access-Control-Allow-Origin 属性为你允许该接口访问的域名.最常见的设置是: res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Credentials', 'true'); // 允许服务器端发送Cookie数据 然而,这样的

  • 详解Java Ajax jsonp 跨域请求

    1.什么是JSONP 一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外.利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP.用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析. JSONP是

随机推荐