javascript
cors跨域_Spring Boot 中通过 CORS 解决跨域问题
(給ImportNew加星標,提高Java技能)
轉(zhuǎn)自:江南一點雨
今天和小伙伴們來聊一聊通過CORS解決跨域問題。
同源策略
很多人對跨域有一種誤解,以為這是前端的事,和后端沒關(guān)系,其實不是這樣的,說到跨域,就不得不說說瀏覽器的同源策略。
同源策略是由Netscape提出的一個著名的安全策略,它是瀏覽器最核心也最基本的安全功能,現(xiàn)在所有支持JavaScript的瀏覽器都會使用這個策略。所謂同源是指協(xié)議、域名以及端口要相同。同源策略是基于安全方面的考慮提出來的,這個策略本身沒問題,但是我們在實際開發(fā)中,由于各種原因又經(jīng)常有跨域的需求,傳統(tǒng)的跨域方案是JSONP,JSONP雖然能解決跨域但是有一個很大的局限性,那就是只支持GET請求,不支持其他類型的請求,而今天我們說的CORS(跨域源資源共享)(CORS,Cross-origin resource sharing)是一個W3C標準,它是一份瀏覽器技術(shù)的規(guī)范,提供了Web服務(wù)從不同網(wǎng)域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,這是JSONP模式的現(xiàn)代版。
在Spring框架中,對于CORS也提供了相應(yīng)的解決方案,今天我們就來看看SpringBoot中如何實現(xiàn)CORS。
實踐
接下來我們就來看看Spring Boot中如何實現(xiàn)這個東西。
首先創(chuàng)建兩個普通的SpringBoot項目,這個就不用我多說,第一個命名為provider提供服務(wù),第二個命名為consumer消費服務(wù),第一個配置端口為8080,第二個配置配置為8081,然后在provider上提供兩個hello接口,一個get,一個post,如下:
@RestControllerpublic class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
@PostMapping("/hello")
public String hello2() {
return "post hello";
}
}
在consumer的resources/static目錄下創(chuàng)建一個html文件,發(fā)送一個簡單的ajax請求,如下:
"app">"button" onclick="btnClick()" value="get_button">
"button" onclick="btnClick2()"value="post_button">
然后分別啟動兩個項目,發(fā)送請求按鈕,觀察瀏覽器控制臺如下:
Access to XMLHttpRequest at 'http://localhost:8080/hello' from origin' http://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注解配置某一個方法接受某一個域的請求,如下:
@RestControllerpublic class HelloController {
@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";
}
}
這個注解表示這兩個接口接受來自http://localhost:8081地址的請求,配置完成后,重啟provider,再次發(fā)送請求,瀏覽器控制臺就不會報錯了,consumer也能拿到數(shù)據(jù)了。
此時觀察瀏覽器請求網(wǎng)絡(luò)控制臺,可以看到響應(yīng)頭中多了如下信息:
這個表示服務(wù)端愿意接收來自http://localhost:8081的請求,拿到這個信息后,瀏覽器就不會再去限制本次請求的跨域了。
provider上,每一個方法上都去加注解未免太麻煩了,在Spring Boot中,還可以通過全局配置一次性解決這個問題,全局配置只需要在配置類中重寫addCorsMappings方法即可,如下:
@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {
@Overridepublic 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,通常縮寫為CSRF或者XSRF,是一種挾制用戶在當前已登錄的Web應(yīng)用程序上執(zhí)行非本意的操作的攻擊方法,舉個例子:
假如一家銀行用以運行轉(zhuǎn)賬操作的URL地址如下:http://icbc.com/aa?bb=cc,那么,一個惡意攻擊者可以在另一個網(wǎng)站上放置如下代碼:?,如果用戶訪問了惡意站點,而她之前剛訪問過銀行不久,登錄信息尚未過期,那么她就會遭受損失。
基于此,瀏覽器在實際操作中,會對請求進行分類,分為簡單請求,預(yù)先請求,帶憑證的請求等,預(yù)先請求會首先發(fā)送一個options探測請求,和瀏覽器進行協(xié)商是否接受請求。默認情況下跨域請求是不需要憑證的,但是服務(wù)端可以配置要求客戶端提供憑證,這樣就可以有效避免csrf攻擊。
推薦閱讀??點擊標題可跳轉(zhuǎn)Spring Boot面試問題集錦
Springboot 優(yōu)雅停止服務(wù)的幾種方法
搞定所有的跨域請求問題 : jsonp & CORS
看完本文有收獲?請轉(zhuǎn)發(fā)分享給更多人
關(guān)注「ImportNew」,提升Java技能
好文章,我在看??
總結(jié)
以上是生活随笔為你收集整理的cors跨域_Spring Boot 中通过 CORS 解决跨域问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 无法执行二进制文件(linu
- 下一篇: 三国志单机安卓版下载(三国志单机安卓版)