成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringBoot 解決跨域請求的幾種姿勢!

開發 前端
在 Spring Boot 服務中可以通過過濾器或者配置類實現全局跨域訪問,也可以通過@CrossOrigin注解實現局部跨域訪問。

01、背景介紹

熟悉 web 系統開發的同學,對下面這樣的錯誤應該不會太陌生。

圖片圖片

之所以會出現這個錯誤,是因為瀏覽器出于安全的考慮,采用同源策略的控制,防止當前站點惡意攻擊 web 服務器盜取數據。

同源策略,簡單的說就是當瀏覽器訪問 web 服務器資源時,只有源相同才能正常進行通信,即協議、域名、端口號都完全一致,否則就屬于跨域請求。當發起跨域請求時,服務端是能收到請求并正常返回結果的,只是結果被瀏覽器攔截了。

像上文中,瀏覽器訪問的站點是http://127.0.0.1:8848/,而站點內發起的接口請求源是http://localhost:8080,因為不同源,所以報跨域請求異常。

由此可見,想要實現接口請求的正常訪問,瀏覽器的訪問站點源和接口請求源,必須得一致。

事實上,在現在流行的前后端分離的開發模式下,很難做到請求源高度一致,那怎么辦呢?

答案肯定是有辦法啦!

雖然瀏覽器出于安全的考慮,默認采用同源策略控制,以便減少服務器被惡意攻擊的機會,但是開發者可以通過CORS協議在瀏覽器內實現站內跨域請求訪問。

實現很簡單,通過在 web 服務器中增加一個特殊的Header響應屬性來告訴瀏覽器解除跨域的限制,如果瀏覽器支持CORS并且判斷允許通過的話,此時發起的跨域請求就可以正常展示了。

常用的 Header 響應屬性如下:

圖片圖片

帶著以上的信息,我們就一起來了解一下如何在 Spring Boot 應用中實現跨域訪問。

02、解決方案

2.1、方法一:采用過濾器的方式全局配置

采用過濾器的方式來實現所有接口支持跨域請求,是一種比較通用的做法,也是 Java web 項目中常用的方法,實現過程如下!

首先,創建一個實現自Filter接口的過濾器,示例如下:

public class CrossFilter implements Filter {

    /**
     * 允許跨域的白名單域名
     */
    private final static Set<String> ALLOW_DOMAINS = new HashSet<>();

    static {
        ALLOW_DOMAINS.add("http://127.0.0.1:8848");
    }


    @Override
    public void init(FilterConfig config) throws ServletException {}

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        // 獲取客戶端原始請求域
        String origin = request.getHeader("Origin");
        String originDomain = removeHttp(origin);
        if(ALLOW_DOMAINS.contains(originDomain)){
            // 在響應對象中,添加CROS協議相關的header屬性
            response.setHeader("Access-Control-Allow-Origin", origin);
            response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,HEAD,PUT,PATCH");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,Authorization,authorization");
            response.setHeader("Access-Control-Allow-Credentials","true");
        }
        //繼續往下傳遞
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {}


    /**
     * 移除http協議頭部
     * @param url
     * @return
     */
    public static String removeHttp(String url){
        return url.replace("http://", "").replace("https://", "");
    }

}

接著,將其注冊到Servlet容器中,示例如下:

@Configuration
public class FilterConfig {

    /**
     * 添加CrossFilter過濾器
     * @return
     */
    @Bean
    public FilterRegistrationBean crossFilterBean() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setName("crossFilter"); // 指定過濾器名稱
        registration.setFilter(new CrossFilter()); // 指定過濾器實現類
        registration.setUrlPatterns(Collections.singleton("/*"));// 指定攔截路徑
        registration.setOrder(1);// 指定順序
        return registration;
    }
}

最后,啟動服務后,再到瀏覽器中發起跨域請求,看看效果如下。

圖片圖片

圖片圖片

從結果上看,瀏覽器成功進行了跨域請求,并展示了服務器返回的結果。

2.2、方法二:通過全局配置類實現跨域訪問

在 Spring Boot 應用,除了采用過濾器的方式實現跨域訪問外,我們還可以通過全局配置類實現跨域訪問。

實現方法也非常簡單,只需要重寫WebMvcConfigurer接口中的addCorsMappings方法即可,示例如下:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .maxAge(3600)
                .allowedHeaders("Origin", "Accept", "Content-Type", "Authorization")
                .allowCredentials(true);
    }
}

其中allowedOrigins("*")表示對所有請求都允許跨域訪問。

2.3、方法三:通過CrossOrigin注解實現跨域訪問

某些場景,如果不希望所有的接口都能跨域訪問,只想在部分接口上放開跨域訪問。此時,可以通過 Spring Boot 提供的@CrossOrigin注解,在對應的方法上加上該注解,即可實現跨域訪問。

示例如下:

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @CrossOrigin
    @PostMapping(value = "/queryAll")
    public List<User> queryAll(){
        List<User> result = userService.queryAll();
        return result;
    }
}

如果使用在controller類上,表示當前類下的所有接口方法都允許跨域訪問。

同時,@CrossOrigin注解也支持設置更小的粒度,示例如下:

@CrossOrigin(origins = "http://domain.com", maxAge = 1800)

更多的屬性行為,內容如下:

  • origins: 允許的源列表,多個源可以使用逗號分隔
  • methods: 允許的 HTTP 方法列表
  • allowedHeaders: 允許的請求頭列表,默認情況下,允許所有請求頭
  • allowCredentials:設置是否允許攜帶憑證
  • maxAge: 預檢請求的緩存時間(以秒為單位)

03、小結

最后總結一下,在 Spring Boot 服務中可以通過過濾器或者配置類實現全局跨域訪問,也可以通過@CrossOrigin注解實現局部跨域訪問。

跨域訪問的配置,更適合在開發環境中方便前后端進行聯調對接。為了安全起見,在上生產的時候,建議將其關閉掉或者做限制。

示例代碼地址:

https://gitee.com/pzblogs/spring-boot-example-demo

04、參考

1.https://cloud.tencent.com/developer/article/1655583

2.https://cloud.tencent.com/developer/article/1924258

責任編輯:武曉燕 來源: 潘志的研發筆記
相關推薦

2023-05-06 15:32:04

2024-10-29 16:41:24

SpringBoot跨域Java

2024-10-18 08:53:49

SpringMybatis微服務

2019-08-29 14:30:16

代碼開發工具

2024-08-02 08:21:52

Spring項目方式

2019-11-11 17:34:16

前端開發技術

2024-12-02 14:30:20

2023-11-17 09:38:21

2019-03-01 09:55:28

HTTPMock架構

2021-04-27 15:20:41

人工智能機器學習技術

2024-08-23 09:00:18

開發跨域請求

2024-05-20 09:28:44

Spring客戶端瀏覽器

2017-05-25 09:45:35

2017-03-12 19:51:38

js實用跨域

2017-08-20 12:49:59

瀏覽器跨域服務器

2020-09-17 13:33:39

開發

2022-04-29 09:11:14

CORS瀏覽器

2009-02-18 09:30:10

AJAX跨域XML

2020-04-13 15:25:01

MySQL數據庫模糊搜索

2024-01-25 11:04:51

跨域問題反向代理層網關層
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲三区在线观看 | 男女视频在线观看免费 | 99精品免费 | 91成人在线视频 | 夜夜爽99久久国产综合精品女不卡 | 国产999精品久久久久久 | 91精品国产综合久久久久蜜臀 | 日韩在线观看网站 | 国产一区二区激情视频 | 欧美激情在线精品一区二区三区 | 在线视频中文字幕 | 男人的天堂在线视频 | 黑人久久| 免费av在线网站 | 国产亚洲精品久久久优势 | 久久久综合精品 | 久久久久久综合 | 福利视频一区二区 | 懂色中文一区二区三区在线视频 | av毛片 | 国产精品午夜电影 | 国产日韩精品一区二区 | 久日精品 | 国产性生活一级片 | 中文字幕高清av | 国产视频久久久久 | 国产区精品视频 | 亚洲91精品 | 久久久久久久一区 | 免费在线观看一级毛片 | av天天看| 日本精品久久久一区二区三区 | 亚洲精品日韩一区二区电影 | 久久99精品久久久久久琪琪 | 久久久久久成人 | 国产一区二区三区日韩 | 精品视频一区二区三区 | 91xxx在线观看 | 一区二区久久精品 | 午夜欧美a级理论片915影院 | 国产综合精品一区二区三区 |