問題描述
后端域名為a.abc.com,前端域名為b.abc.com。瀏覽器在訪問時,會出現(xiàn)跨域訪問。瀏覽器對于javascript的同源策略的限制。
http請求時,請求本身會返回200,但是返回結(jié)果不會走success,并且會在瀏覽器console中提示:
已攔截跨源請求:同源策略禁止讀取位于 https://www.baidu.com/ 的遠程資源。(原因:cors 頭缺少 ‘access-control-allow-origin')。
解決方案
1.jsonp
2.引用a站的js
3.nginx做a站的反向代理
4.后端服務(wù)放開跨域請求
其中,以最后兩種見常。
詳細方案
本文主要描述第四種解決方案:后端服務(wù)放開跨域請求。
spring boot中放開跨域請求很簡單。
1.增加一個configuration類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
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訪問可以正常進行了,但是會不會有什么問題呢?
對于大部分網(wǎng)站依然需要使用cookie作為前后端傳輸數(shù)據(jù)的媒介,然而默認非同源請求是不攜帶cookie信息的。
2.服務(wù)端允許跨域攜帶cookie信息
在spring boot2.0.2中,允許跨域設(shè)置比較簡單,只需增加一個configuration類即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
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)整
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
$.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ā)生錯誤!' ); } }); |
此時,當前端向后端服務(wù)做跨域請求時,增加
1
2
3
|
xhrfields:{ withcredentials: true }, |
就會帶上cookie信息了,同理會帶上token/sessionid等等內(nèi)容。
測試方法
spring boot中增加一個controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@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,來訪問跨域訪問。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<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)效果,并不一定要形成服務(wù)訪問。
當服務(wù)端不允許跨域訪問時,html文件訪問均報錯,并調(diào)用失敗。
當服務(wù)端允許跨域訪問時,html請求訪問成功。
當服務(wù)端開啟cookie傳遞,并在html文件中增加 xhrfields參數(shù)時,session生效
。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://www.wencst.com/archives/1635