SpringBoot跨域問題的五種解決方式
一、什么是跨域 CORS
當(dāng)一臺(tái)服務(wù)器資源從另一臺(tái)服務(wù)器(不同 的域名或者端口)請(qǐng)求一個(gè)資源或者接口,就會(huì)發(fā)起一個(gè)跨域 HTTP 請(qǐng)求。
舉個(gè)簡(jiǎn)單的例子,從http://aaa.com/index.html,發(fā)送一個(gè) Ajax 請(qǐng)求,請(qǐng)求地址是 http://bbb.com/下面的一個(gè)接口,這就是發(fā)起了一個(gè)跨域請(qǐng)求。在不做任何處理的情況下,這個(gè)跨域請(qǐng)求是無法被成功請(qǐng)求的
現(xiàn)在很多項(xiàng)目開發(fā)都是前后端分離的,前端和后端都是獨(dú)立運(yùn)行的,后端提供json數(shù)據(jù)格式。那么兩邊是不同的ip、端口,跨站點(diǎn)進(jìn)行資源分享,就是跨域。所以前后端分離就肯定有跨域問題。
二、為什么會(huì)有跨域問題
瀏覽器出于安全考慮,會(huì)限制跨域訪問,就是不允許跨域請(qǐng)求資源,要求協(xié)議,IP和端口必須都相同,其中有一個(gè)不同就會(huì)產(chǎn)生跨域問題,這就是同源策略。
三、有哪些跨域類型
簡(jiǎn)單來說,就是協(xié)議、域名(主域或子域)、端口號(hào)有一個(gè)不同就是跨域。
四、解決跨域問題的五種方式
1. 添加跨域配置類
* 號(hào)根據(jù)需要修改。
@Configuration public class GlobalCorsConfig { @Bean public CorsFilter corsFilter() { //1. 添加 CORS配置信息 CorsConfiguration config = new CorsConfiguration(); //放行哪些原始域 config.addAllowedOrigin("*"); //是否發(fā)送 Cookie config.setAllowCredentials(true); //放行哪些請(qǐng)求方式 config.addAllowedMethod("*"); //放行哪些原始請(qǐng)求頭部信息 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
在控制器(類上)上使用注解 @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. 自定義過濾器
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; @Component public class MyCorsFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest httpServletRequest = (HttpServletRequest) req; response.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("origin")); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With"); response.setHeader("Access-Control-Allow-Credentials", "true"); chain.doFilter(req, res); } public void init(FilterConfig filterConfig) {} public void destroy() {} }
5. 手動(dòng)設(shè)置響應(yīng)頭
在接口的代碼中添加下面這端代碼。
response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); response.addHeader("Access-Control-Max-Age", "1800");//30 min
前后分離的跨域問題其他解決方案
Nginx服務(wù)器反向代理
通過反向代理服務(wù)器監(jiān)聽同端口,同域名的訪問,不同路徑映射到不同的地址,比如,在nginx服務(wù)器中,監(jiān)聽同一個(gè)域名和端口,不同路徑轉(zhuǎn)發(fā)到客戶端和服務(wù)器,把不同端口和域名的限制通過反向代理,來解決跨域的問題。
server { listen 80; server_name abc.com; #charset koi8-r; #access_log logs/host.access.log main; location /client { #訪問客戶端路徑 proxy_pass http://localhost:81; proxy_redirect default; } location /apis { #訪問服務(wù)器路徑 rewrite ^/apis/(.*)$ /$1 break; proxy_pass http://localhost:82; } }
或者直接在Nginx中進(jìn)行配置
location / { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers X-Requested-With; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS; if ($request_method = 'OPTIONS') { return 204; } }
總結(jié)
到此這篇關(guān)于SpringBoot跨域問題的五種解決方式的文章就介紹到這了,更多相關(guān)SpringBoot跨域問題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
簡(jiǎn)單介紹線性表以及如何實(shí)現(xiàn)雙鏈表
本文先介紹線性表的幾個(gè)基本組成部分:數(shù)組、單向鏈表、雙向鏈表;隨后給出雙向鏈表的C、C++和Java三種語(yǔ)言的實(shí)現(xiàn),需要的朋友可以參考下2015-07-07解決SpringBoot打成jar運(yùn)行后無法讀取resources里的文件問題
這篇文章主要介紹了解決SpringBoot打成jar運(yùn)行后無法讀取resources里的文件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08在SpringBoot中注入RedisTemplate實(shí)例異常的解決方案
這篇文章主要介紹了在SpringBoot中注入RedisTemplate實(shí)例異常的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01Java8通過CompletableFuture實(shí)現(xiàn)異步回調(diào)
這篇文章主要介紹了Java8通過CompletableFuture實(shí)現(xiàn)異步回調(diào),CompletableFuture是Java?8?中新增的一個(gè)類,它是對(duì)Future接口的擴(kuò)展,下文關(guān)于其更多相關(guān)詳細(xì)介紹需要的小伙伴可以參考一下2022-04-04一天時(shí)間用Java寫了個(gè)飛機(jī)大戰(zhàn)游戲,朋友直呼高手
前兩天我發(fā)現(xiàn)論壇有兩篇飛機(jī)大戰(zhàn)的文章異常火爆,但都是python寫的,竟然不是我大Java,說實(shí)話作為老java選手,我心里是有那么一些失落的,今天特地整理了這篇文章,需要的朋友可以參考下2021-05-05Spring調(diào)度框架EnableScheduling&Scheduled源碼解析
這篇文章主要介紹了Spring調(diào)度框架EnableScheduling&Scheduled源碼解析,@EnableScheduling&Scheduled定時(shí)調(diào)度框架,本著不僅知其然還要知其所以然的指導(dǎo)思想,下面對(duì)該調(diào)度框架進(jìn)行源碼解析,以便更好的理解其執(zhí)行過程,需要的朋友可以參考下2024-01-01Spring使用注解實(shí)現(xiàn)Bean的自動(dòng)裝配
大家好,本篇文章主要講的是Spring使用注解實(shí)現(xiàn)Bean的自動(dòng)裝配,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02