1. 程式人生 > >SpringBoot系列(八)分分鐘學會Springboot多種解決跨域方式

SpringBoot系列(八)分分鐘學會Springboot多種解決跨域方式

SpringBoot系列(八) 分分鐘學會SpringBoot多種跨域解決方式

往期推薦
SpringBoot系列(一)idea新建Springboot專案

SpringBoot系列(二)入門知識

springBoot系列(三)配置檔案詳解

SpringBoot系列(四)web靜態資源配置詳解

SpringBoot系列(五)Mybatis整合完整詳細版

SpringBoot系列(六)整合thymeleaf詳解版

Springboot系列(七) 整合介面文件swagger,使用,測試

** 目錄 **

  • 1. 跨域怎麼理解
  • 2. SprinBoot中跨域的三種解決方法
    • 1. CrossOrigin註解
    • 2. 實現WebMvcConfigurer
    • 3. 過濾器配置
  • 3. 跨域測試
  • 4.總結:

1. 跨域怎麼理解

跨域是什麼?

 跨域是指不同域名之間的相互訪問,這是由瀏覽器的同源策略決定的,是瀏覽器對JavaScript施加的安全措施,防止惡意檔案破壞。

同源策略:同源策略是一種約定,它是瀏覽器最核心的也是最基本的安全策略,如果缺少了同源策略,則瀏覽器的正常功能可能會受到影響。
所謂同源就是說協議 ,域名,埠號完全一致,有一個不一致就會造成跨域問題。

跨域原理:

  • 跨域請求能正常發出去,服務端能接受到請求並正常返回結果,只是結果被攔截了。
  • 跨域只存在於瀏覽器,不存在於其他平臺,比如安卓/java/ios等平臺。
  • 之所以會發生跨域是因為受到了同源策略的限制,同源策略要求源相同才能進行正常通訊,即協議,域名,埠號都完全一致。

URL :統一資源定位符,它是www的統一資源定位標誌,也就是我們說的網路地址。它的一般格式為:協議型別://伺服器地址:埠號/路徑。
這也就是我們說的跨域中的域。

2. SprinBoot中跨域的三種解決方法

跨域技術CORS:

 CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源伺服器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。

 SpringBoot 就對Cross 做了很好的支援。目前有三種跨域方式。

1. CrossOrigin註解

//@CrossOrigin  表示所有的URL均可訪問此資源
@CrossOrigin(origins = "http://127.0.0.1:8093")//表示只允許這一個url可以跨域訪問這個controller
@RestController
@RequestMapping("/testCorss")
public class CorssOriginController {

    //可以對方法運用該註解
    //@CrossOrigin(origins = "http://127.0.0.1:8093")
    @GetMapping("/getString")
    public String getString(){
        return "跨域成功!";
    }

}

 程式碼說明:@CrossOrigin這個註解用起來很方便,這個可以用在方法上,也可以用在類上。如果你不設定他的value屬性,或者是origins屬性,就預設是可以允許所有的URL/域訪問。

  • value屬性可以設定多個URL。
  • origins屬性也可以設定多個URL。
  • maxAge屬性指定了準備響應前的快取持續的最大時間。就是探測請求的有效期。
  • allowCredentials屬性表示使用者是否可以傳送、處理 cookie。預設為false
  • allowedHeaders 屬性表示允許的請求頭部有哪些。
  • methods 屬性表示允許請求的方法,預設get,post,head。

2. 實現WebMvcConfigurer

/**
 * @author 全棧學習筆記
 * @date 2020/4/21 12:04
 * @description
 */
public class MyWebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/testCross/**")
                .allowedHeaders("*")
                .allowedMethods("*")
                .allowCredentials(true)
                .allowedOrigins("http://localhost:8093")
                .maxAge(2000);
    }
}

 這個沒什麼好說的,就重寫addCorsMappings方法就行,配置好引數,引數和上面的註解的引數類似。這個配置屬於全域性配置,配置好了全部的介面都遵循此規則。上面的註解方式只對類或者方法生效。addMaping是設定對那種格式的URL生效,也就是跟在URL後面的路徑。

3. 過濾器配置


import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * @author 全棧學習筆記
 * @date 2020/4/21 12:49
 * @description
 */
@Configuration
public class Filter {
    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:8093");//*表示允許所有
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config); // CORS 配置對所有介面都有效
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }

}

 利用過濾器配置實現跨域,還有另外一種方法

package com.example.democrossorigin.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.FilterConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
public class CorssFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        res.addHeader("Access-Control-Allow-Credentials", "true");
        res.addHeader("Access-Control-Allow-Origin", "http://localhost:8093");
        res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
        chain.doFilter(request, response);
    }
    @Override
    public void destroy() {
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
}

3. 跨域測試

 我們在新建一個SpringBoot web專案,然後在resources 資料夾裡面的static 新建一個index.html
程式碼如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<body>
<div id="test"></div>
<input type="button" value="測試資料" onclick="getString()"/>
</body>
<script>

    function getString() {
        $.ajax({
            url:'http://localhost:8092/testCorss/getString',
            type:'get',
            data:{},
            success:function (msg) {
                $("#test").html(msg);
            }
        })
    }
</script>
</html>

 我們模擬一個ajax請求,來請求我們的8092埠,執行新的專案結果

 點選測試,發起請求

 成功從一個專案裡面拿到了另外一個專案的資料,就說明我們的跨域是成功了的。

4.總結:##

 本文講述了跨域的產生原因,原理,以及同源策略的概念,然後介紹了在SpringBoot解決跨域的三種方式,分別是利用CrossOrgin註解,全域性配置Mvc,然後就是利用過濾器配置,過濾器有兩種方式,有一種是利用servlet的過濾器實現。如果你覺得本文有用的話!點個贊也不錯哦!你的贊是對我最大的鼓勵和支援