好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

详解Spring Boot 2.0.2+Ajax解决跨域请求的问题

问题描述

后端域名为a.abc测试数据,前端域名为b.abc测试数据。浏览器在访问时,会出现跨域访问。浏览器对于javascript的同源策略的限制。

http请求时,请求本身会返回200,但是返回结果不会走success,并且会在浏览器console中提示:

已拦截跨源请求:同源策略禁止读取位于 https://HdhCmsTestbaidu测试数据/ 的远程资源。(原因:cors 头缺少 ‘access-control-allow-origin')。

解决方案

1.jsonp

2.引用a站的js

3.nginx做a站的反向代理

4.后端服务放开跨域请求

其中,以最后两种见常。

详细方案

本文主要描述第四种解决方案:后端服务放开跨域请求。

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访问可以正常进行了,但是会不会有什么问题呢?

对于大部分网站依然需要使用cookie作为前后端传输数据的媒介,然而默认非同源请求是不携带cookie信息的。

2.服务端允许跨域携带cookie信息

在spring boot2.0.2中,允许跨域设置比较简单,只需增加一个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);

  }

}

增加信息后,在前端依然需要调整ajax请求,才能在非同源请求中携带cookie信息。

3.前端调整

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

$.ajax({

  url: 'http://beta.roboming测试数据/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( '服务器发生错误!' );

  }

});

此时,当前端向后端服务做跨域请求时,增加

?

1

2

3

xhrfields:{

   withcredentials: true

},

就会带上cookie信息了,同理会带上token/sessionid等等内容。

测试方法

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测试数据/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文件可以单独本地访问即可出现效果,并不一定要形成服务访问。

当服务端不允许跨域访问时,html文件访问均报错,并调用失败。

当服务端允许跨域访问时,html请求访问成功。

当服务端开启cookie传递,并在html文件中增加 xhrfields参数时,session生效 。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://HdhCmsTestwencst测试数据/archives/1635

查看更多关于详解Spring Boot 2.0.2+Ajax解决跨域请求的问题的详细内容...

  阅读:18次