詳解Spring Boot 2.0.2+Ajax解決跨域請求的問題
問題描述
后端域名為A.abc.com,前端域名為B.abc.com。瀏覽器在訪問時,會出現(xiàn)跨域訪問。瀏覽器對于javascript的同源策略的限制。
HTTP請求時,請求本身會返回200,但是返回結果不會走success,并且會在瀏覽器console中提示:
已攔截跨源請求:同源策略禁止讀取位于 https://www.baidu.com/ 的遠程資源。(原因:CORS 頭缺少 ‘Access-Control-Allow-Origin')。
解決方案
1.jsonp
2.引用A站的js
3.Nginx做A站的反向代理
4.后端服務放開跨域請求
其中,以最后兩種見常。
詳細方案
本文主要描述第四種解決方案:后端服務放開跨域請求。
spring boot中放開跨域請求很簡單。
1.增加一個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訪問可以正常進行了,但是會不會有什么問題呢?
對于大部分網站依然需要使用cookie作為前后端傳輸數(shù)據的媒介,然而默認非同源請求是不攜帶cookie信息的。
2.服務端允許跨域攜帶cookie信息
在spring boot2.0.2中,允許跨域設置比較簡單,只需增加一個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);
}
}
增加信息后,在前端依然需要調整AJAX請求,才能在非同源請求中攜帶cookie信息。
3.前端調整
$.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('服務器發(fā)生錯誤!');
}
});
此時,當前端向后端服務做跨域請求時,增加
xhrFields:{
withCredentials:true
},
就會帶上cookie信息了,同理會帶上token/sessionID等等內容。
測試方法
spring boot中增加一個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;
}
}
增加一個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文件可以單獨本地訪問即可出現(xiàn)效果,并不一定要形成服務訪問。
當服務端不允許跨域訪問時,html文件訪問均報錯,并調用失敗。
當服務端允許跨域訪問時,html請求訪問成功。
當服務端開啟cookie傳遞,并在html文件中增加 xhrFields參數(shù)時,session生效。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
基于JavaSwing+mysql開發(fā)一個學生社團管理系統(tǒng)設計和實現(xiàn)
項目使用Java swing+mysql開發(fā),可實現(xiàn)基礎數(shù)據維護、用戶登錄注冊、社團信息列表查看、社團信息添加、社團信息修改、社團信息刪除以及退出注銷等功能、界面設計比較簡單易學、適合作為Java課設設計以及學習技術使用,需要的朋友參考下吧2021-08-08
解決Eclipse配置Tomcat出現(xiàn)Cannot create a server using the selected
這篇文章主要介紹了解決Eclipse配置Tomcat出現(xiàn)Cannot create a server using the selected type錯誤的相關資料,需要的朋友可以參考下2017-02-02
String類型傳遞是值傳遞,char[]類型傳遞是引用傳遞的實現(xiàn)
下面小編就為大家?guī)硪黄猄tring類型傳遞是值傳遞,char[]類型傳遞是引用傳遞的實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看不2016-09-09
synchronized?和?Lock?的異同點(如何讓選擇)
這篇文章主要介紹了?synchronized和Lock的異同點(如何讓選擇),文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09
SpringBoot詳解如果通過@Value注解給靜態(tài)變量注入值
這篇文章主要介紹了springboot如何通過@Value給靜態(tài)變量注入值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06

