Spring boot跨域設(shè)置實(shí)例詳解
定義:跨域是指從一個(gè)域名的網(wǎng)頁(yè)去請(qǐng)求另一個(gè)域名的資源
1.原由
公司內(nèi)部有多個(gè)不同的子域,比如一個(gè)是location.company.com ,而應(yīng)用是放在app.company.com , 這時(shí)想從 app.company.com去訪問(wèn) location.company.com 的資源就屬于跨域
本人是springboot菜鳥(niǎo),但是做測(cè)試框架后端需要使用Springboot和前端對(duì)接,出現(xiàn)跨域問(wèn)題,需要設(shè)置后端Response的Header.走了不少坑,在這總結(jié)一下以備以后使用
2.使用場(chǎng)景
瀏覽器默認(rèn)不允許跨域訪問(wèn),包括我們平時(shí)ajax也是限制跨域訪問(wèn)的。
產(chǎn)生跨域訪問(wèn)的情況主要是因?yàn)檎?qǐng)求的發(fā)起者與請(qǐng)求的接受者1、域名不同;2、端口號(hào)不同
如果一個(gè)網(wǎng)頁(yè)可以隨意地訪問(wèn)另外一個(gè)網(wǎng)站的資源,那么就有可能在客戶(hù)完全不知情的情況下出現(xiàn)安全問(wèn)題
3.解決方案
通過(guò)設(shè)置Access-Control-Allow-Origin來(lái)實(shí)現(xiàn)跨域訪問(wèn)
4.具體解決
剛開(kāi)始使用http://www.jianshu.com/p/f2060a6d6e3b設(shè)置,但是由于我們使用的spring版本的問(wèn)題,CorsConfiguration類(lèi)需要4.2.7版本。和我們使用的spring里面版本不一致,導(dǎo)致版本沖突或者各種問(wèn)題
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1
corsConfiguration.addAllowedHeader("*"); // 2
corsConfiguration.addAllowedMethod("*"); // 3
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4
return new CorsFilter(source);
}
}
后來(lái)改為Filter方式
@Component
public class CorsFilter implements Filter {
final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class);
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest reqs = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Credentials", "true");
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");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
后來(lái)改為Filter方式
@Component
public class CorsFilter implements Filter {
final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class);
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest reqs = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Credentials", "true");
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");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
網(wǎng)上很多資料都是教按以上方法設(shè)置,但是我這里就是設(shè)置不成功的。出現(xiàn)下面問(wèn)題
<span style="color:#ff0000;">Fetch API cannot load https://atfcapi.alpha.elenet.me/atfcapi/project/mainPageList. The value of the 'Access-Control-Allow-Origin' </span>
<span style="color:#ff0000;">header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'https://atfcapi-test.faas.elenet.me' is therefore not allowed access.</span>
目前為止,不知道為什么這樣配置不可以,然后改為設(shè)置單個(gè)域名,如下顯示
response.setHeader("Access-Control-Allow-Origin", "https://atfcapi-test.faas.elenet.me");
這樣設(shè)置就成功了,但是我們有好幾個(gè)環(huán)境,同一套代碼,寫(xiě)死一個(gè)域名并解決不了問(wèn)題,
按照很多網(wǎng)絡(luò)文章中所說(shuō),設(shè)置多個(gè)域名如下:
response.setHeader("Access-Control-Allow-Origin", "https://atfcapi-test.faas.elenet.me,https://atfcapi-test-beta.faas.elenet.me");
但是設(shè)置完以后,并不好用,出現(xiàn)如下錯(cuò)誤信息:
<span style="color:#ff6666;">Fetch API cannot load https://atfcapi.alpha.elenet.me/atfcapi/project/getProjects. The 'Access-Control-Allow-Origin' header contains multiple values </span>
<span style="color:#ff6666;">'https://atfcapi-test.faas.elenet.me,https://atfcapi-test-beta.faas.elenet.me', but only one is allowed. Origin 'https://atfcapi-test.faas.elenet.me' is therefore not allowed access. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.</span>
設(shè)置為以下方式也還是錯(cuò)誤:
response.setHeader("Access-Control-Allow-Origin", "https://atfcapi-test.faas.elenet.me");
response.setHeader("Access-Control-Allow-Origin", "https://atfcapi-test-beta.faas.elenet.me");
最后采用了一種和設(shè)置為* 的方式一樣的辦法,代碼如下:
@Component
public class CorsFilter implements Filter {
final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CorsFilter.class);
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest reqs = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin",reqs.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
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");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
從request 中的header中獲取Origin,來(lái)做配置,最終成功并滿(mǎn)足需求。
其實(shí)有些東西還是一知半解,但是起碼曲線救國(guó)也是一種解決方法。
總結(jié)
以上就是本文關(guān)于Spring boot跨域設(shè)置實(shí)例詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:
如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
- SpringBoot解決ajax跨域問(wèn)題的方法
- Spring boot 總結(jié)之跨域處理cors的方法
- vue+springboot前后端分離實(shí)現(xiàn)單點(diǎn)登錄跨域問(wèn)題解決方法
- 淺談spring-boot 允許接口跨域并實(shí)現(xiàn)攔截(CORS)
- Spring Boot實(shí)現(xiàn)跨域訪問(wèn)實(shí)現(xiàn)代碼
- Spring Boot Web應(yīng)用開(kāi)發(fā) CORS 跨域請(qǐng)求支持
- spring boot配合前端實(shí)現(xiàn)跨域請(qǐng)求訪問(wèn)
- Java Spring boot 2.0 跨域問(wèn)題的解決
相關(guān)文章
spring中12種@Transactional的失效場(chǎng)景(小結(jié))
日常我們進(jìn)行業(yè)務(wù)開(kāi)發(fā)時(shí),基本上使用的都是聲明式事務(wù),即為使用@Transactional注解的方式,本文主要介紹了spring中12種@Transactional的失效場(chǎng)景,感興趣的小伙伴們可以參考一下2022-01-01
springboot實(shí)現(xiàn)熱部署操作方法
這篇文章主要介紹了springboot實(shí)現(xiàn)熱部署操作方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
java String.split 無(wú)法使用小數(shù)點(diǎn)分割的問(wèn)題
這篇文章主要介紹了java String.split 無(wú)法使用小數(shù)點(diǎn)分割的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
springMvc和mybatis-plus中枚舉值和字段的映射
這篇文章主要為大家介紹了springMvc和mybatis-plus中枚舉值和字段的映射示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
mybatis xml注釋sql的注意事項(xiàng)及說(shuō)明
這篇文章主要介紹了mybatis xml注釋sql的注意事項(xiàng)及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
一分鐘掌握J(rèn)ava?Quartz定時(shí)任務(wù)
這篇文章主要為大家介紹了Java?Quartz定時(shí)任務(wù)一分鐘掌握教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
Java在排序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置的方法詳解
相信大家在操作Java的時(shí)候經(jīng)常會(huì)要在一個(gè)數(shù)組(無(wú)序)中查找元素的第一個(gè)和最后一個(gè)位置,下面這篇文章主要給大家介紹了關(guān)于Java在排序數(shù)組中查找元素的第一個(gè)和最后一個(gè)位置的相關(guān)資料,需要的朋友可以參考下2024-01-01

