SpringBoot 中實現跨域的 5 種方式

作者_:ratelfu_

blog.csdn.net/weter_drop/article/details/112135940

一、爲什麼會出現跨域問題

出於瀏覽器的同源策略限制。同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說 Web 是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。

同源策略會阻止一個域的 javascript 腳本和另外一個域的內容進行交互。所謂同源(即指在同一個域)就是兩個頁面具有相同的協議(protocol),主機(host)和端口號(port)

二、什麼是跨域

當一個請求 url 的協議、域名、端口三者之間任意一個與當前頁面 url 不同即爲跨域

三、非同源限制

【1】無法讀取非同源網頁的 Cookie、LocalStorage 和 IndexedDB

【2】無法接觸非同源網頁的 DOM

【3】無法向非同源地址發送 AJAX 請求

四、java 後端 實現 CORS 跨域請求的方式

對於 CORS 的跨域請求,主要有以下幾種方式可供選擇:

  1. 返回新的 CorsFilter

  2. 重寫 WebMvcConfigurer

  3. 使用註解 @CrossOrigin

  4. 手動設置響應頭 (HttpServletResponse)

  5. 自定 web filter 實現跨域

注意:

  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);
    }
}
  1. 重寫 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("*");
    }
}
  1. 使用註解 (局部跨域)

在控制器 (類上) 上使用註解 @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";
    }
  1. 手動設置響應頭 (局部跨域)

使用 HttpServletResponse 對象添加響應頭 (Access-Control-Allow-Origin) 來授權原始域,這裏 Origin 的值也可以設置爲 “*”, 表示全部放行。推薦:150 道常見的 Java 面試題分解彙總

@RequestMapping("/index")
public String index(HttpServletResponse response) {
    response.addHeader("Access-Allow-Control-Origin","*");
    return "index";
}
  1. 使用自定義 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 中配置這個過濾器,使其生效

<!-- 跨域訪問 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  -->

五、 參考連接

  1. https://blog.csdn.net/pjmike233/article/details/82461911

  2. https://blog.csdn.net/zlbdmm/article/details/105853736

  3. https://www.cnblogs.com/lenve/p/11724463.html

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/aN9KCwBV7C8ovrA-RL55uQ