最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于SpringBoot中的跨域問題

 更新時間:2023年08月10日 09:45:41   作者:ycfxhsw  
這篇文章主要介紹了關(guān)于SpringBoot中的跨域問題,同源策略是由Netscape提出的一個著名的安全策略,它是瀏覽器最核心也最基本的安全功能,現(xiàn)在所有支持JavaScript的瀏覽器都會使用這個策略,需要的朋友可以參考下

一、同源策略

同源策略是由Netscape提出的一個著名的安全策略,它是瀏覽器最核心也最基本的安全功能,現(xiàn)在所有支持JavaScript的瀏覽器都會使用這個策略。

所謂同源是指 協(xié)議 、 域名 以及 端口 要相同。

同源策略是基于安全方面的考慮提出來的,這個策略本身沒問題,但是我們在實際開發(fā)中,由于各種原因又經(jīng)常有跨域的需求,傳統(tǒng)的跨域方案是JSONP,JSONP雖然能解決跨域但是有一個很大的局限性,那就是只支持GET請求,不支持其他類型的請求

而今天我們說的CORS(跨域源資源共享)(CORS,Cross-origin resource sharing)是一個W3C標(biāo)準(zhǔn),它是一份瀏覽器技術(shù)的規(guī)范,提供了Web服務(wù)從不同網(wǎng)域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,這是JSONP模式的現(xiàn)代版。

在Spring框架中,對于CORS也提供了相應(yīng)的解決方案。

非同源限制

  • 無法讀取非同源網(wǎng)頁的 Cookie、LocalStorage 和 IndexedDB
  • 無法接觸非同源網(wǎng)頁的 DOM
  • 無法向非同源地址發(fā)送 AJAX 請求

二、java后端實現(xiàn)CORS跨域請求的方式

  1. 返回新的CorsFilter
  2. 重寫 WebMvcConfigurer
  3. 使用注解 @CrossOrigin
  4. 手動設(shè)置響應(yīng)頭 (HttpServletResponse)
  5. 自定web filter 實現(xiàn)跨域

注意:

  • CorFilter / WebMvConfigurer / @CrossOrigin 需要 SpringMVC 4.2以上版本才支持,對應(yīng)springBoot 1.3版本以上
  • 上面前兩種方式屬于全局 CORS 配置,后兩種屬于局部 CORS配置。如果使用了局部跨域是會覆蓋全局跨域的規(guī)則,所以可以通過 @CrossOrigin 注解來進(jìn)行細(xì)粒度更高的跨域資源控制。
  • 其實無論哪種方案,最終目的都是修改響應(yīng)頭,向響應(yīng)頭中添加瀏覽器所要求的數(shù)據(jù),進(jìn)而實現(xiàn)跨域

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

在任意配置類,返回一個 新的 CorsFIlter Bean ,并添加映射路徑和具體的CORS配置路徑。

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1. 添加 CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //放行哪些原始域
        config.addAllowedOrigin("*");
        //是否發(fā)送 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("/**")
              //是否發(fā)送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. 手動設(shè)置響應(yīng)頭(局部跨域)

使用 HttpServletResponse 對象添加響應(yīng)頭(Access-Control-Allow-Origin)來授權(quán)原始域,這里 Origin的值也可以設(shè)置為 “*”,表示全部放行。

@RequestMapping("/index")
public String index(HttpServletResponse response) {
    response.addHeader("Access-Allow-Control-Origin","*");
    return "index";
}

5. 使用自定義filter實現(xiàn)跨域

首先編寫一個過濾器,可以起名字為MyCorsFilter.java

@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  -->

三、例子

首先創(chuàng)建兩個普通的SpringBoot項目,第一個命名為provider提供服務(wù),第二個命名為consumer消費服務(wù),第一個配置端口為8080,第二個配置配置為8081,然后在provider上提供兩個hello接口,一個get,一個post,如下:

@RestController
public class Provider {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
    @PostMapping("/hello")
    public String hello2() {
        return "post hello";
    }
}

在consumer的resources/templates目錄下創(chuàng)建一個html文件,發(fā)送一個簡單的ajax請求,如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>CORS</title>
  </head>
  <body>
    <div id="app"></div>
    <input type="button" onclick="btnClick()" value="get_button">
    <input type="button" onclick="btnClick2()" value="post_button">
    <script>
        function btnClick() {
            $.get('http://localhost:8080/hello', function (msg) {
                $("#app").html(msg);
            });
        }
        function btnClick2() {
            $.post('http://localhost:8080/hello', function (msg) {
                $("#app").html(msg);
            });
        }
    </script>
  </body>
</html>

然后分別啟動兩個項目,發(fā)送請求按鈕,觀察瀏覽器控制臺如下:

Access to XMLHttpRequest at ‘//localhost:8080/hello’ from origin ‘//localhost:8081’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource

可以看到,由于同源策略的限制,請求無法發(fā)送成功。

使用CORS可以在前端代碼不做任何修改的情況下,實現(xiàn)跨域,那么接下來看看在provider中如何配置。首先可以通過@CrossOrigin注解配置某一個方法接受某一個域的請求,如下:

@RestController
public class Provider {
    @CrossOrigin(value = "http://localhost:8081")
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
    @CrossOrigin(value = "http://localhost:8081")
    @PostMapping("/hello")
    public String hello2() {
        return "post hello";
    }
}

這個注解表示這兩個接口接受來自//localhost:8081地址的請求,配置完成后,重啟provider,再次發(fā)送請求,瀏覽器控制臺就不會報錯了,consumer也能拿到數(shù)據(jù)了。

provider上,每一個方法上都去加注解未免太麻煩了,在Spring Boot中,還可以通過全局配置一次性解決這個問題,全局配置只需要在配置類中重寫addCorsMappings方法即可,如下:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:8081")
                .allowedMethods("*")
                .allowedHeaders("*");
    }
}

/**表示本應(yīng)用的所有方法都會去處理跨域請求,allowedMethods表示允許通過的請求數(shù),allowedHeaders則表示允許的請求頭。經(jīng)過這樣的配置之后,就不必在每個方法上單獨配置跨域了。

四、存在的問題

了解了整個CORS的工作過程之后,我們通過Ajax發(fā)送跨域請求,雖然用戶體驗提高了,但是也有潛在的威脅存在,常見的就是CSRF(Cross-site request forgery)跨站請求偽造。跨站請求偽造也被稱為one-click attack 或者 session riding,通??s寫為CSRF或者XSRF,是一種挾制用戶在當(dāng)前已登錄的Web應(yīng)用程序上執(zhí)行非本意的操作的攻擊方法,舉個例子:

假如一家銀行用以運行轉(zhuǎn)賬操作的URL地址如下://icbc.com/aa?bb=cc,那么,一個惡意攻擊者可以在另一個網(wǎng)站上放置如下代碼:<img src="//icbc.com/aa?bb=cc">,如果用戶訪問了惡意站點,而她之前剛訪問過銀行不久,登錄信息尚未過期,那么她就會遭受損失。

基于此,瀏覽器在實際操作中,會對請求進(jìn)行分類,分為簡單請求,預(yù)先請求,帶憑證的請求等,預(yù)先請求會首先發(fā)送一個options探測請求,和瀏覽器進(jìn)行協(xié)商是否接受請求。默認(rèn)情況下跨域請求是不需要憑證的,但是服務(wù)端可以配置要求客戶端提供憑證,這樣就可以有效避免csrf攻擊。

到此這篇關(guān)于關(guān)于SpringBoot中的跨域問題的文章就介紹到這了,更多相關(guān)SpringBoot 跨域內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java長整除問題淺談

    java長整除問題淺談

    這篇文章主要介紹了java長整除問題,有需要的朋友可以參考一下
    2013-11-11
  • SpringBoot中的Thymeleaf模板

    SpringBoot中的Thymeleaf模板

    Thymeleaf 的出現(xiàn)是為了取代 JSP,雖然 JSP 存在了很長時間,并在 Java Web 開發(fā)中無處不在,但是它也存在一些缺陷。在這篇文中給大家介紹了這些缺陷所存在問題,對spring boot thymeleaf 模板相關(guān)知識感興趣的朋友跟隨小編一起看看吧
    2018-10-10
  • Java入門教程--帶包的類如何編譯與運行

    Java入門教程--帶包的類如何編譯與運行

    我們一般都是通過IDE(如Eclipse、Intellij Idea,STS等)來開發(fā),調(diào)試java項目。在不借助IDE的情況下,如何編譯、運行Java程序。打包編譯時,會自動創(chuàng)建包目錄,不需要自己新建包名文件夾。
    2022-12-12
  • Java中Struts2的值棧ValueStack詳解

    Java中Struts2的值棧ValueStack詳解

    這篇文章主要介紹了Java中Struts2的值棧ValueStack詳解,值棧(ValueStack)就是 OGNL 表達(dá)式存取數(shù)據(jù)的地方,在一個值棧中,封裝了一次請求所需要的所有數(shù)據(jù),需要的朋友可以參考下
    2023-08-08
  • SpringBoot實現(xiàn)數(shù)據(jù)加密脫敏的示例代碼

    SpringBoot實現(xiàn)數(shù)據(jù)加密脫敏的示例代碼

    這篇文章主要為大家學(xué)習(xí)介紹了SpringBoot如何利用注解+反射+AOP實現(xiàn)數(shù)據(jù)加密脫敏的功能,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2023-08-08
  • Java 中實現(xiàn)異步的多種方式

    Java 中實現(xiàn)異步的多種方式

    文章介紹了Java中實現(xiàn)異步處理的幾種常見方式,每種方式都有其特點和適用場景,通過選擇合適的異步處理方式,可以提高程序的性能和可維護(hù)性,感興趣的朋友一起看看吧
    2025-03-03
  • JVM原理之類加載的全過程

    JVM原理之類加載的全過程

    文章詳細(xì)介紹了Java類加載過程,包括加載、鏈接、初始化、使用和卸載五個階段,并解釋了符號引用和直接引用的區(qū)別,以及類變量和實例變量的區(qū)別,此外,還介紹了Class.forName()方法的作用和使用場景
    2025-01-01
  • Springboot如何根據(jù)docx填充生成word文件并導(dǎo)出pdf

    Springboot如何根據(jù)docx填充生成word文件并導(dǎo)出pdf

    這篇文章主要介紹了Springboot如何根據(jù)docx填充生成word文件并導(dǎo)出pdf問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 使用Postman自動生成Cookie并轉(zhuǎn)換為Java代碼的實現(xiàn)

    使用Postman自動生成Cookie并轉(zhuǎn)換為Java代碼的實現(xiàn)

    在接口測試中,有時候需要在請求中攜帶Cookie信息,為了方便測試,我們可以使用Postman來自動生成Cookie,并將其轉(zhuǎn)換為Java代碼,以便在自動化測試中使用,下面將介紹如何實現(xiàn)這一功能,需要的朋友可以參考下
    2024-11-11
  • Tk.mybatis零sql語句實現(xiàn)動態(tài)sql查詢的方法(4種)

    Tk.mybatis零sql語句實現(xiàn)動態(tài)sql查詢的方法(4種)

    有時候,查詢數(shù)據(jù)需要根據(jù)條件使用動態(tài)查詢,這時候需要使用動態(tài)sql,本文主要介紹了Tk.mybatis零sql語句實現(xiàn)動態(tài)sql查詢的方法,感興趣的可以了解一下
    2021-12-12

最新評論

丹江口市| 庄河市| 晴隆县| 通许县| 新巴尔虎右旗| 枞阳县| 皮山县| 柯坪县| 新郑市| 盐津县| 高尔夫| 福鼎市| 静乐县| 深州市| 化德县| 泰和县| 舒城县| 渝中区| 拜城县| 甘德县| 黄浦区| 秦皇岛市| 天镇县| 偏关县| 陇西县| 封开县| 镇坪县| 原阳县| 台南市| 莱阳市| 屏山县| 突泉县| 长沙市| 久治县| 河间市| 高安市| 黎平县| 景东| 仪征市| 迭部县| 阿图什市|