SpringBoot解決跨域請求攔截

 

前言 

同源策略:判斷是不是同源的,主要看這三點,協議,ip,端口。html

同源策略就是瀏覽器出於網站安全性的考慮,限制不一樣源之間的資源相互訪問的一種政策。前端

好比在域名https://www.baidu.com下,腳本不可以訪問https://www.sina.com源下的資源,不然將會被瀏覽器攔截。jquery

 

注意兩點:git

1.必須是腳本請求,好比AJAX請求。github

可是以下狀況不會產生跨域攔截web

<img src="xxx"/>
<a href='xxx"> </a>

2.跨域攔截是前端請求已經發出,而且在後端返回響應時檢查相關參數,是否容許接收後端請求。後端

 

 在微服務開發中,一個系統包含多個微服務,會存在跨域請求的場景。跨域

 

本文主要講解SpringBoot解決跨域請求攔截的問題。瀏覽器

 

搭建項目

這裏建立兩個web項目,web1 和 web2.安全

web2項目請求web1項目的資源。

這裏只貼關鍵代碼,完整代碼參考GitHub

WEB2

建立一個Controller返回html頁面

@Slf4j
@Controller
public class HomeController {

    @RequestMapping("/index")
    public String home(){
        log.info("/index");

        return "/home";
    }
}

 

html頁面 home.html

這裏建立了一個按鈕,按鈕按下則請求資源:"http://localhost:8301/hello"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>web2</title>

    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
    </script>

    <script>
        $(function () {
            
            $("#testBtn").click(function () {
                console.log("testbtn ...");
                $.get("http://localhost:8301/hello",function(data,status){
                    alert("數據: " + data + "\n狀態: " + status);
                });
            })
            
        })

    </script>
</head>
<body>
    web2
    <button id="testBtn">測試</button>
</body>
</html>

 

WEB1

@Slf4j
@RestController
public class Web1Controller {

    @RequestMapping("/hello")
    public String hello(){
        log.info("hello ");
        return "hello," + new Date().toString();
    }
}

 這裏配置兩個項目爲不一樣的端口。

WEB1爲8301

WEB2爲8302

所以是不一樣源的。 

測試

在web1尚未配置容許跨域訪問的狀況下

按下按鈕,將會出現錯誤。顯示Header中沒有Access-Control-Allow-Origin

Access to XMLHttpRequest at 'http://localhost:8301/hello' from origin 'http://localhost:8300' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

 

 

WEB1添加容許跨域請求,經過實現WebMvcConfigurer

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/hello");
    }
}

 

再次訪問將會返回正常數據。

除了以上的配置外,還能夠作更細緻的限制

好比對請求的headers,請求的方法POST/GET...。請求的源進行限制。

 

同時還可使用註解 @CrossOrigin來替換上面的配置。

@Slf4j
@RestController
public class Web1Controller {

    @CrossOrigin
    @RequestMapping("/hello")
    public String hello(){
        log.info("hello ");
        return "hello," + new Date().toString();
    }
}

 

 

註解能夠用在類上,也能夠用在方法上,但必須是控制器類

配置和上面同樣,也是能夠對方法,header,源進行個性化限制。

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
    /** @deprecated */
    @Deprecated
    String[] DEFAULT_ORIGINS = new String[]{"*"};
    /** @deprecated */
    @Deprecated
    String[] DEFAULT_ALLOWED_HEADERS = new String[]{"*"};
    /** @deprecated */
    @Deprecated
    boolean DEFAULT_ALLOW_CREDENTIALS = false;
    /** @deprecated */
    @Deprecated
    long DEFAULT_MAX_AGE = 1800L;

    @AliasFor("origins")
    String[] value() default {};

    @AliasFor("value")
    String[] origins() default {};

    String[] allowedHeaders() default {};

    String[] exposedHeaders() default {};

    RequestMethod[] methods() default {};

    String allowCredentials() default "";

    long maxAge() default -1L;
}
相關文章
相關標籤/搜索