SpringBoot跨域問(wèn)題的五種解決方式
一、什么是跨域 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)求是無(wú)法被成功請(qǐng)求的
現(xiàn)在很多項(xiàng)目開發(fā)都是前后端分離的,前端和后端都是獨(dú)立運(yùn)行的,后端提供json數(shù)據(jù)格式。那么兩邊是不同的ip、端口,跨站點(diǎn)進(jìn)行資源分享,就是跨域。所以前后端分離就肯定有跨域問(wèn)題。
二、為什么會(huì)有跨域問(wèn)題
瀏覽器出于安全考慮,會(huì)限制跨域訪問(wèn),就是不允許跨域請(qǐng)求資源,要求協(xié)議,IP和端口必須都相同,其中有一個(gè)不同就會(huì)產(chǎn)生跨域問(wèn)題,這就是同源策略。
三、有哪些跨域類型
簡(jiǎn)單來(lái)說(shuō),就是協(xié)議、域名(主域或子域)、端口號(hào)有一個(gè)不同就是跨域。

四、解決跨域問(wèn)題的五種方式
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. 自定義過(guò)濾器
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
前后分離的跨域問(wèn)題其他解決方案
Nginx服務(wù)器反向代理
通過(guò)反向代理服務(wù)器監(jiān)聽同端口,同域名的訪問(wèn),不同路徑映射到不同的地址,比如,在nginx服務(wù)器中,監(jiān)聽同一個(gè)域名和端口,不同路徑轉(zhuǎn)發(fā)到客戶端和服務(wù)器,把不同端口和域名的限制通過(guò)反向代理,來(lái)解決跨域的問(wèn)題。
server {
listen 80;
server_name abc.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location /client { #訪問(wèn)客戶端路徑
proxy_pass http://localhost:81;
proxy_redirect default;
}
location /apis { #訪問(wèn)服務(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跨域問(wèn)題的五種解決方式的文章就介紹到這了,更多相關(guān)SpringBoot跨域問(wèn)題內(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)行后無(wú)法讀取resources里的文件問(wèn)題
這篇文章主要介紹了解決SpringBoot打成jar運(yùn)行后無(wú)法讀取resources里的文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
在SpringBoot中注入RedisTemplate實(shí)例異常的解決方案
這篇文章主要介紹了在SpringBoot中注入RedisTemplate實(shí)例異常的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
Java8通過(guò)CompletableFuture實(shí)現(xiàn)異步回調(diào)
這篇文章主要介紹了Java8通過(guò)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,說(shuō)實(shí)話作為老java選手,我心里是有那么一些失落的,今天特地整理了這篇文章,需要的朋友可以參考下2021-05-05
Spring調(diào)度框架EnableScheduling&Scheduled源碼解析
這篇文章主要介紹了Spring調(diào)度框架EnableScheduling&Scheduled源碼解析,@EnableScheduling&Scheduled定時(shí)調(diào)度框架,本著不僅知其然還要知其所以然的指導(dǎo)思想,下面對(duì)該調(diào)度框架進(jìn)行源碼解析,以便更好的理解其執(zhí)行過(guò)程,需要的朋友可以參考下2024-01-01
Spring使用注解實(shí)現(xiàn)Bean的自動(dòng)裝配
大家好,本篇文章主要講的是Spring使用注解實(shí)現(xiàn)Bean的自動(dòng)裝配,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02

