Spring boot 解決 CORS跨域問題

運(yùn)行環(huán)境

操作系統(tǒng):Windows 10 十气;
開發(fā)工具:IDEA-2019.3;
Web服務(wù)器:Tomcat 9.0.24春霍;
JDK版本: jdk 1.8.0_221砸西;
Spring boot版本:2.0.9.RELEASE

開始

想起最早搭建spring boot框架的時(shí)候,就遇到了跨域的問題址儒。當(dāng)時(shí)芹枷,也嘗試去解決,雖然莲趣,最終解決了鸳慈,但是,總是感覺稀里糊涂的喧伞。
這次看了公眾號(hào)的文章《Cors跨域(一):深入理解跨域請求概念及其根因》走芋,又燃起了我嘗試重新梳理跨域問題的想法。

若想實(shí)現(xiàn)Cors機(jī)制的跨域請求潘鲫,是需要瀏覽器和服務(wù)器同時(shí)支持的翁逞。關(guān)于瀏覽器對CORS的支持情況:現(xiàn)在都2021年了,so可以認(rèn)為100%的瀏覽器都是支持的溉仑,再加上CORS的整個(gè)過程都由瀏覽器自動(dòng)完成挖函,前端無需做任何設(shè)置,所以前端工程師的ajax原來怎么用現(xiàn)在還是怎么用浊竟,它對前段開發(fā)人員是完全透明的怨喘。

我摘錄了文章的一段話,從上面可以看出來振定,B/S架構(gòu)下的項(xiàng)目哲思,前端我們不做任何修改,我們主要解決的后端的問題吩案。而后端的處理的目的也是為了讓前端知道后端是如何允許跨域請求的棚赔。

方法1. 使用Filter過濾器解決

這里不依賴spring boot。主要思路就是開發(fā)一個(gè)Filter,并讓Spring容器去掃描注冊靠益。

@Component
//filter雖然是servlet的三大組件之一丧肴,但是也是需要顯式的注冊在xml中的,后續(xù)servlet3.0后支持注解配置胧后,使用@componet注解芋浮,
//讓spring 去掃描filter,并注冊使用
public class CORSFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, 
          ServletResponse servletResponse, FilterChain chain) 
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        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", "content-type,Authorization");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        chain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

方法2:配置FilterRegistrationBean

注意FilterRegistrationBean是spring boot框架提供的一個(gè)類壳快。這個(gè)類為我們注冊filter提供了便捷纸巷。我們要注冊的也是spring-web內(nèi)部提供的CorsFilter。

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        //跨域相關(guān)配置
        Map<String, CorsConfiguration> corsConfigs = new LinkedHashMap<>();
        corsConfigs.put("*", new CorsConfiguration().applyPermitDefaultValues());
        corsConfigs.put("/**", new CorsConfiguration().applyPermitDefaultValues());
        //組裝跨域ConfigurationSource
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.setCorsConfigurations(corsConfigs);
        //組裝CorsFilter
        CorsFilter corsFilter = new CorsFilter(configSource);
        //注冊filter
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(corsFilter);
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName("corsFilter");
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

方法3:使用@CrossOrigin

使用@CrossOrigin眶痰,能夠更加細(xì)粒度的控制跨域請求瘤旨。

    @CrossOrigin
    @RequestMapping("/home")
    public String home(Model model) {
        return "home";
    }

方法4:使用WebMvcConfigurer方式全局配置

使用spring mvc 提供的接口WebMvcConfigurer配置跨域。

@Configuration
public class WebSecurityConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                //該字段是必須的竖伯,用來列出瀏覽器的CORS請求會(huì)用到哪些HTTP方法存哲,
                .allowedMethods("GET","POST","PUT","DELETE","OPTIONS")
                //該字段是一個(gè)逗號(hào)分隔的字符串,指定瀏覽器CORS請求會(huì)額外發(fā)送的頭信息字段七婴,上例是X-Custom-Header祟偷。
                .allowedHeaders("Access-Control-Allow-Origin","token","secret")
                //CORS請求時(shí),XMLHttpRequest對象的getResponseHeader()方法只能拿到6個(gè)基本字段打厘。如果想拿到其他字段修肠,就必須在Access-Control-Expose-Headers里面指定。
                //.exposedHeaders("token","secret")
                .allowCredentials(true)//它的值是一個(gè)布爾值户盯,表示是否允許發(fā)送Cookie氛赐。默認(rèn)情況下,Cookie不包括在CORS請求之中
                //該字段可選先舷,用來指定本次預(yù)檢請求的有效期,單位為秒
                .maxAge(3600);
    }
}

上面4中方法滓侍,第一種用了servlet的知識(shí)蒋川,第二種用了spring boot的知識(shí),第三種用了spring框架的細(xì)粒度控制注解撩笆,第四種是spring框架提供專門跨域解決方案捺球。
第一種最好理解,第四種是最優(yōu)雅解決方案夕冲。

總結(jié)

在解決這個(gè)問題的時(shí)候氮兵,由于涉及的知識(shí)塊很多。會(huì)遇到的宏觀問題有:

  • 1.你不知道這是屬于spring框架的歹鱼,spring boot的泣栈,還是servlet的。
  • 2.這是幾個(gè)知識(shí)塊組合才能解決的。
  • 3.可以從任意一個(gè)知識(shí)塊的角度出發(fā)都可以解決這個(gè)問題南片,條條大路通羅馬掺涛。

你在解決這個(gè)問題之前,這3個(gè)問題始終都會(huì)纏繞在一起疼进,讓人禿頭薪缆。等回頭看,這3個(gè)問題都有三個(gè)正確的答案伞广。但是拣帽,我們又浪費(fèi)了很多的時(shí)間。
我從別人身上學(xué)到一個(gè)優(yōu)點(diǎn)嚼锄,就是减拭,以解決問題為導(dǎo)向。最重要的灾票,是先要解決問題峡谊,不要管解決的方案是不是很啰嗦,是不是不優(yōu)雅刊苍。只有解決了問題既们,才能回過頭剖析問題,優(yōu)化方案正什。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末啥纸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子婴氮,更是在濱河造成了極大的恐慌斯棒,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件主经,死亡現(xiàn)場離奇詭異荣暮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)罩驻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門穗酥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惠遏,你說我怎么就攤上這事砾跃。” “怎么了节吮?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵抽高,是天一觀的道長。 經(jīng)常有香客問我透绩,道長翘骂,這世上最難降的妖魔是什么壁熄? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮雏胃,結(jié)果婚禮上请毛,老公的妹妹穿的比我還像新娘。我一直安慰自己瞭亮,他們只是感情好方仿,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著统翩,像睡著了一般仙蚜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上厂汗,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天委粉,我揣著相機(jī)與錄音,去河邊找鬼娶桦。 笑死贾节,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的衷畦。 我是一名探鬼主播栗涂,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼祈争!你這毒婦竟也來了斤程?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤菩混,失蹤者是張志新(化名)和其女友劉穎忿墅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沮峡,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疚脐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了邢疙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棍弄。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖秘症,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情式矫,我是刑警寧澤乡摹,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站采转,受9級(jí)特大地震影響聪廉,放射性物質(zhì)發(fā)生泄漏瞬痘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一板熊、第九天 我趴在偏房一處隱蔽的房頂上張望框全。 院中可真熱鬧,春花似錦干签、人聲如沸津辩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喘沿。三九已至,卻和暖如春竭贩,著一層夾襖步出監(jiān)牢的瞬間蚜印,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工留量, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窄赋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓楼熄,卻偏偏與公主長得像忆绰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子孝赫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容