Spring?MVC跨域問題及解決
跨域問題
不同的域
協(xié)議、域名、端口,三者只要有一個不同,就叫不同的域
比如:
從http:/moon.com/test
去拉取下列url對應的資源
URL | 是否跨域 |
---|---|
http:/moon.com/test | 不算跨域 |
http:/www.moon.com/test | 算跨域 |
https:/moon.com/test | 算跨域 |
Tips:
- 不同的域?qū)?strong>協(xié)議、域名、端口三者的檢查是非常嚴格的,比如從
http://localhost:8080/test
去拉取http://127.0.0.1:8080/test2
是算跨域的,因為域名不一樣,雖然他們表達的意思一樣。
同源策略
瀏覽器自身會組織從一個域加載的腳本獲取另外一個域的資源
Tips:
- 對于css和js這樣的資源是不會觸發(fā)同源策略
解決方法
1.CORS
跨域資源共享,因為它支持所有類型的HTTP請求
Tips:
- 只能解決瀏覽器跨域問題,如果涉及到App,小程序,物聯(lián)網(wǎng)設(shè)備跨域,SpringMVC這一套不一定生效
2.JSONP
前端可以通過JSONP來進行獲取跨域資源,但是只支持GET請求
3.局部解決方案
@CrossOrigin
在方法或者類上加上@CrossOrigin
這個注解,設(shè)置響應頭中允許的跨域訪問的請求域,*
代表所有,也可以通過字符串數(shù)組的形式進行逐一放行
@CrossOrigin({"http://localhost:8081", "http://localhost:8082"}) @GetMapping("/request") public Student rest1(HttpServletResponse response) { Student student = new Student(); student.setName("GET曉龍"); student.setAge(23); student.setBirthday(new Date()); return student; }
Tips:
- 注解中的maxAge屬性表示預檢請求結(jié)果緩存的最大時長,單位為秒,默認為1800s,即30分鐘
4.全局解決方法
對于瀏覽器的跨域問題,其實有很多的解決方案,其本質(zhì)就是設(shè)置響應頭中的內(nèi)容Access-Control-Allow-Origin
的值,他的值其實就是我們上面允許訪問的域,對此我們只需要配置響應的響應頭,所以我們可以通過過濾器去設(shè)置響應頭,貨值配置Spring幫我們寫好的過濾
手寫過濾器
我們寫一個類是實現(xiàn)Filter
接口,因為在Filter
接口中,初始化和銷毀方法是默認實現(xiàn),我們這里也不需要,所以沒有進行重寫。
public class CrossOriginFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 轉(zhuǎn)化響應 HttpServletResponse response = (HttpServletResponse) servletResponse; // 設(shè)置響應頭,設(shè)置允許訪問為全部 response.setHeader("Access-Control-Allow-Origin", "*"); // 放行 filterChain.doFilter(servletRequest, response); } }
Tips:
- 過濾器寫好以后,我們把它配置到項目中即可,可以使用web.xml或者java類的方式配置,具體方式可以參考之前的配置過濾器
配置Spring配置文件
在多數(shù)的情況下,我們是不需要去手寫過濾器,Spring已經(jīng)幫我們做好了,而且功能也比我們的完善,我們可以直接拿過來用
<!--配置mvc的跨域訪問--> <mvc:cors> <!-- 映射中對應的就是我們的請求url,配置哪一條允許跨域訪問 allowed-origins =>允許訪問的請求 allowed-methods =>允許訪問的方式 max-age =>預檢請求緩存時間 --> <mvc:mapping path="/rest/**" allowed-origins="*" allowed-methods="POST" max-age="1888"/> </mvc:cors>
Tips:
- path中,如果寫成
/rest/*
的話表示rest下面的子代請求,不會去請求到孫子代,比如/rest/test/test2
是請求不到的 - 如果寫成
/rest/**
的話表示rest下面的所有后代的請求,比如/rest/test/test2
是可以請求到的
配置JavaConfig
使用Java類來進行配置其實也是大同小異,而且在WebMvcConfig
接口中,已經(jīng)為我們提供了對應的方法addCorsMappings
,我們只需要重新該方法即可。
@Override public void addCorsMappings(CorsRegistry registry) { /* * 在注冊處添加Mapping,參數(shù)值就是對應配置文件里面path * 然后就可以一直去點,對應的配置xml里面的屬性 */ registry.addMapping("/rest/**") .allowedOrigins("*") .allowedMethods("POST") .maxAge(1811); }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java如何實現(xiàn)圖片轉(zhuǎn)化為數(shù)據(jù)流
這篇文章主要介紹了java如何實現(xiàn)圖片轉(zhuǎn)化為數(shù)據(jù)流,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01springsecurity中http.permitall與web.ignoring的區(qū)別說明
這篇文章主要介紹了springsecurity中http.permitall與web.ignoring的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08