一、为什么会出现跨域问题

出于浏览器的同源策略限制。同源策略(sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

二、什么是跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

三、非同源限制

【1】无法读取非同源网页的 cookie、localstorage 和 indexeddb
【2】无法接触非同源网页的 dom
【3】无法向非同源地址发送 ajax 请求

四、java 后端 实现 cors 跨域请求的方式

对于 cors的跨域请求,主要有以下几种方式可供选择:

  • 返回新的corsfilter
  • 重写 webmvcconfigurer
  • 使用注解 @crossorigin
  • 手动设置响应头 (httpservletresponse)
  • 自定web filter 实现跨域

注意:

  • corfilter / webmvconfigurer / @crossorigin 需要 springmvc 4.2以上版本才支持,对应springboot 1.3版本以上
  • 上面前两种方式属于全局 cors 配置,后两种属于局部 cors配置。如果使用了局部跨域是会覆盖全局跨域的规则,所以可以通过 @crossorigin 注解来进行细粒度更高的跨域资源控制。
  • 其实无论哪种方案,最终目的都是修改响应头,向响应头中添加浏览器所要求的数据,进而实现跨域 。

1.返回新的 corsfilter(全局跨域)

在任意配置类,返回一个 新的 corsfilter bean ,并添加映射路径和具体的cors配置路径。

@configuration
public class globalcorsconfig {
  @bean
  public corsfilter corsfilter() {
    //1. 添加 cors配置信息
    corsconfiguration config = new corsconfiguration();
    //放行哪些原始域
    config.addallowedorigin("*");
    //是否发送 cookie
    config.setallowcredentials(true);
    //放行哪些请求方式
    config.addallowedmethod("*");
    //放行哪些原始请求头部信息
    config.addallowedheader("*");
    //暴露哪些头部信息
    config.addexposedheader("*");
    //2. 添加映射路径
    urlbasedcorsconfigurationsource corsconfigurationsource = new urlbasedcorsconfigurationsource();
    corsconfigurationsource.registercorsconfiguration("/**",config);
    //3. 返回新的corsfilter
    return new corsfilter(corsconfigurationsource);
  }
}

2. 重写 webmvcconfigurer(全局跨域)

@configuration
public class corsconfig implements webmvcconfigurer {
  @override
  public void addcorsmappings(corsregistry registry) {
    registry.addmapping("/**")
        //是否发送cookie
        .allowcredentials(true)
        //放行哪些原始域
        .allowedorigins("*")
        .allowedmethods(new string[]{"get", "post", "put", "delete"})
        .allowedheaders("*")
        .exposedheaders("*");
  }
}

3. 使用注解 (局部跨域)

在控制器(类上)上使用注解 @crossorigin:,表示该类的所有方法允许跨域。

@restcontroller
@crossorigin(origins = "*")
public class hellocontroller {
  @requestmapping("/hello")
  public string hello() {
    return "hello world";
  }
}

在方法上使用注解 @crossorigin:

@requestmapping("/hello")
  @crossorigin(origins = "*")
   //@crossorigin(value = "http://localhost:8081") //指定具体ip允许跨域
  public string hello() {
    return "hello world";
  }

4. 手动设置响应头(局部跨域)

使用 httpservletresponse 对象添加响应头(access-control-allow-origin)来授权原始域,这里 origin的值也可以设置为 “*”,表示全部放行。推荐:150道常见的java面试题分解汇总

@requestmapping("/index")
public string index(httpservletresponse response) {
  response.addheader("access-allow-control-origin","*");
  return "index";
}

5. 使用自定义filter实现跨域

首先编写一个过滤器,可以起名字为mycorsfilter.java

package com.mesnac.aop;

import java.io.ioexception;
import javax.servlet.filter;
import javax.servlet.filterchain;
import javax.servlet.filterconfig;
import javax.servlet.servletexception;
import javax.servlet.servletrequest;
import javax.servlet.servletresponse;
import javax.servlet.http.httpservletresponse;
import org.springframework.stereotype.component;
@component
public class mycorsfilter implements filter {
 public void dofilter(servletrequest req, servletresponse res, filterchain chain) throws ioexception, servletexception {
  httpservletresponse response = (httpservletresponse) res;
  response.setheader("access-control-allow-origin", "*");
  response.setheader("access-control-allow-methods", "post, get, options, delete");
  response.setheader("access-control-max-age", "3600");
  response.setheader("access-control-allow-headers", "x-requested-with,content-type");
  chain.dofilter(req, res);
 }
 public void init(filterconfig filterconfig) {}
 public void destroy() {}
}

在web.xml中配置这个过滤器,使其生效2021java面试宝典

<!-- 跨域访问 start-->
<filter>
 <filter-name>corsfilter</filter-name>
 <filter-class>com.mesnac.aop.mycorsfilter</filter-class>
</filter>
<filter-mapping>
 <filter-name>corsfilter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 跨域访问 end -->

到此这篇关于springboot 中实现跨域的5种方式小结的文章就介绍到这了,更多相关springboot 跨域内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!