詳解Spring Boot 2.0.2+Ajax解決跨域請求的問題
問題描述
后端域名為A.abc.com,前端域名為B.abc.com。瀏覽器在訪問時(shí),會出現(xiàn)跨域訪問。瀏覽器對于javascript的同源策略的限制。
HTTP請求時(shí),請求本身會返回200,但是返回結(jié)果不會走success,并且會在瀏覽器console中提示:
已攔截跨源請求:同源策略禁止讀取位于 https://www.baidu.com/ 的遠(yuǎn)程資源。(原因:CORS 頭缺少 ‘Access-Control-Allow-Origin')。
解決方案
1.jsonp
2.引用A站的js
3.Nginx做A站的反向代理
4.后端服務(wù)放開跨域請求
其中,以最后兩種見常。
詳細(xì)方案
本文主要描述第四種解決方案:后端服務(wù)放開跨域請求。
spring boot中放開跨域請求很簡單。
1.增加一個(gè)configuration類
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; /** * 跨域訪問配置 * @author wencst * @creation 2017年8月18日 */ @Configuration public class CustomCORSConfiguration { private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); return corsConfiguration; } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); return new CorsFilter(source); } }
增加此類以后,非同源http訪問可以正常進(jìn)行了,但是會不會有什么問題呢?
對于大部分網(wǎng)站依然需要使用cookie作為前后端傳輸數(shù)據(jù)的媒介,然而默認(rèn)非同源請求是不攜帶cookie信息的。
2.服務(wù)端允許跨域攜帶cookie信息
在spring boot2.0.2中,允許跨域設(shè)置比較簡單,只需增加一個(gè)configuration類即可。
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; /** * 跨域訪問配置 * @author wencst * @creation 2017年8月18日 */ @Configuration public class CustomCORSConfiguration { private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.addExposedHeader("Content-Type"); corsConfiguration.addExposedHeader( "X-Requested-With"); corsConfiguration.addExposedHeader("accept"); corsConfiguration.addExposedHeader("Origin"); corsConfiguration.addExposedHeader( "Access-Control-Request-Method"); corsConfiguration.addExposedHeader("Access-Control-Request-Headers"); corsConfiguration.setAllowCredentials(true); return corsConfiguration; } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); return new CorsFilter(source); } }
增加信息后,在前端依然需要調(diào)整AJAX請求,才能在非同源請求中攜帶cookie信息。
3.前端調(diào)整
$.ajax({ url: 'http://beta.roboming.com/api.php?s=/Public/AdminLogin.html', type: 'POST', async:true, xhrFields:{ withCredentials:true }, data: { username:userName, password:pwd }, success: function(respon){ console.log(respon); var res=eval(respon); }, error: function(){ alert('服務(wù)器發(fā)生錯(cuò)誤!'); } });
此時(shí),當(dāng)前端向后端服務(wù)做跨域請求時(shí),增加
xhrFields:{ withCredentials:true },
就會帶上cookie信息了,同理會帶上token/sessionID等等內(nèi)容。
測試方法
spring boot中增加一個(gè)controller
@Controller public class LoginController { @RequestMapping(value = "setString") @ResponseBody public String setString(HttpServletRequest request, HttpServletResponse response,@RequestParam String value) { request.getSession().setAttribute("username", value); return "OK"; } @RequestMapping(value = "getString") @ResponseBody public String getString(HttpServletRequest request, HttpServletResponse response) { String username = (String)request.getSession().getAttribute("username"); return username; } }
增加一個(gè)index.html,來訪問跨域訪問。
<html> <head> <meta charset="utf-8"> <title>跨域請求</title> <script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script> </head> <body> <button onclick="set()">set</button> <br><br> <button onclick="get()">get</button> <script> function set(){ $.ajax({ url:'http://wencst.vicp.net/setString?value=10', xhrFields:{ withCredentials:true }, success:function(result){ alert(result); } }); } function get(){ $.ajax({ url:'http://wencst.vicp.net/getString', xhrFields:{ withCredentials:true }, success:function(result){ alert(result); } }); } </script> </body> </html>
html文件可以單獨(dú)本地訪問即可出現(xiàn)效果,并不一定要形成服務(wù)訪問。
當(dāng)服務(wù)端不允許跨域訪問時(shí),html文件訪問均報(bào)錯(cuò),并調(diào)用失敗。
當(dāng)服務(wù)端允許跨域訪問時(shí),html請求訪問成功。
當(dāng)服務(wù)端開啟cookie傳遞,并在html文件中增加 xhrFields參數(shù)時(shí),session生效
。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解決RedisTemplate存儲至緩存數(shù)據(jù)出現(xiàn)亂碼的情況
這篇文章主要介紹了解決RedisTemplate存儲至緩存數(shù)據(jù)出現(xiàn)亂碼的情況,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03Java+MySQL實(shí)現(xiàn)圖書管理系統(tǒng)(完整代碼)
這篇文章主要介紹了Java+MySQL實(shí)現(xiàn)圖書管理系統(tǒng)(完整代碼),本文給大家介紹的非常想詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01基于Java實(shí)現(xiàn)一個(gè)自己的HTTP瀏覽器
這篇文章主要為大家詳細(xì)介紹了如何基于Java實(shí)現(xiàn)一個(gè)自己的HTTP瀏覽器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01java面向?qū)ο笤O(shè)計(jì)原則之迪米特法則分析詳解
這篇文章主要為大家介紹了java面向?qū)ο笤O(shè)計(jì)原則之迪米特法則的示例分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,學(xué)有所得2021-10-10Java Web開發(fā)入門書籍實(shí)例解析(總結(jié)一)
從事Java Web開發(fā)這一段時(shí)間來,對Java 面向?qū)ο蟮乃枷牒蚆VC開發(fā)模式可以說已經(jīng)熟悉了。我當(dāng)前參與的項(xiàng)目使用的框架是Spring、SpringMVC、Hibernate。下面腳本之家小編給大家整理一篇教程幫助大家學(xué)習(xí)javaweb相關(guān)知識,感興趣的朋友可以參考下2016-03-03怎樣提高mybatis-plus中saveBatch方法的效率
這篇文章主要介紹了怎樣提高mybatis-plus中saveBatch方法的效率問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07java Long類型轉(zhuǎn)為String類型的兩種方式及區(qū)別說明
這篇文章主要介紹了java Long類型轉(zhuǎn)為String類型的兩種方式及區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09JavaWeb響應(yīng)下載功能實(shí)例代碼(包含工具類)
今天通過本文給大家分享的是關(guān)于javaweb的響應(yīng)(response)下載功能,需要的朋友參考下吧2017-07-07