gpt4 book ai didi

springboot+jsonp解决前端跨域问题小结

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 25 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章springboot+jsonp解决前端跨域问题小结由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

现在咱们一起来讨论浏览器跨域请求数据的相关问题。说这样可能不是很标准,因为拒绝跨域请求数据并不是浏览器所独有的,之所以会出现跨域请求不了数据,是因为浏览器基本都实现了一个叫"同源策略"的安全规范。该规范具体是什么呢?我们在mdn上找到了一份资料,地址如下:

浏览器同源策略讲解 。

总的来说,当a网址和b网址在 协议 、 端口 、 域名 方面存在不同时,浏览器就会启动同源策略,拒绝a、b服务器之间进行数据请求.

说了同源策略,纸上得来终觉浅,绝知此事要躬行,到底同源策略是怎么体现的呢?下面我将结合代码一步一步进行演示.

1、a服务器请求不了b服务器的情况 。

既然是跨域,我就假设我有两个域名,分别是 a 和 localhost , a 表示小编在阿里云上主机域名, localhost 顾名思义就是小编的开发机器了。我们想象这样一个场景,在 localhost 上部署一个 index.html 文件,在 a 服务器上部署一个简单的 spring-boot 后台服务,并提供一个简单的接口暴露给 index.html 文件调用,最后浏览器请求 localhost 的 index.html 文件,看浏览器提示什么?

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
<!doctype html>
<html>
<head>
<title>测试跨域访问</title>
<meta charset= "utf-8" />
</head>
<body>
   <script src= "https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js" ></script>
   <script type= "text/javascript" >
     $(document).ready(function() {
       $.ajax({
         type : "get" ,
         async : true ,
         url : "http://a/hello/map/getuser.json" ,// 请求a服务器上的接口
         type : "json" ,
         success : function(data) {
         // 打印返回的数据
         console.log( "success,and return data is " + data);
         }
       });
     });
   </script>
     <h2>hello world</h2>
</body>
</html>

浏览器上请求 index.html 文件,显示如下:

springboot+jsonp解决前端跨域问题小结

可以发现,请求被浏览器给拒绝了,提示我们不允许跨域请求数据,很难受,怎么解决呢?

2、使用 jsonp 解决跨域请求 。

首先讲下原理,jsonp解决跨域问题主要利用了 <script> 标签的可跨域性,也就是 src 属性中的链接地址可以跨域访问的特性,因为我们经常将 src 属性值设置为cdn的地址,已加载相关的js库.

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
<!doctype html>
<html>
<head>
<title>测试跨域访问</title>
<meta charset= "utf-8" />
</head>
<body>
   <script src= "https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js" ></script>
   <script type= "text/javascript" >
    $(document).ready(function() {
      $.ajax({
      type : "get" ,
      async : true ,
      jsonp : "callbackname" , // 后端接口参数名
      jsonpcallback : "callbackfunction" , // 回调函数名
      url : "http://a/hello/map/getuser.json" ,
      datatype : "jsonp" , // 数据格式为 jsonp
      success : function(data) {
       console.log( "success" );
      }
      });
    });
   </script>
   <script type= "text/javascript" >
    var callbackfunction = function(data) {
    alert( '接口返回的数据是:' + json.stringify(data));
    };
   </script>
</body>
</html>

a 服务器上的接口代码为:

?
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
37
38
39
40
41
42
43
44
45
/**
  *
  * the class jsonbackcontroller.
  *
  * description:该控制器返回一串简单的json数据,json数据由一个简单的user对象组成
  *
  * @author: huangjiawei
  * @since: 2018年6月12日
  * @version: $revision$ $date$ $lastchangedby$
  *
  */
@restcontroller
@requestmapping (value = "/map" )
public class jsonbackcontroller {
   private static final logger logger = loggerfactory.getlogger(jsonbackcontroller. class );
   /**
    * 解决跨域请求数据
    * @param response
    * @param callbackname 前端回调函数名
    * @return
    */
   @requestmapping (value = "getuser.json" )
   public void getuser(httpservletresponse response, @requestparam string callbackname) {
     user user = new user( "huangjiawei" , 22 );
     response.setcontenttype( "text/javascript" );
     writer writer = null ;
     try {
      writer = response.getwriter();
      writer.write(callbackname + "(" );
      writer.write(user.tostring());
      writer.write( ");" );
     } catch (ioexception e) {
      logger.error( "jsonp响应写入失败! 数据:" + user.tostring(), e);
     } finally {
      if (writer != null ) {
      try {
       writer.close();
      } catch (ioexception e) {
       logger.error( "输出流关闭异常!" , e);
      }
      writer = null ;
      }
     }
   }
}

后端传入一个参数 callbackname 回调函数名,然后返回一段js代码给前端,js代码格式如下:

callbackname + ( data ) + ,

浏览器请求 localhost 服务器上的 index.html 文件,结果如下:

springboot+jsonp解决前端跨域问题小结

上面这种方式是通过 jquery + jsonp 解决跨域问题的,刚刚不是说可以用 <script> 标签的 src 属性吗?四的.

localhost 服务器上的 index.html 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!doctype html>
<html>
<head>
<title>测试跨域访问</title>
<meta charset= "utf-8" />
</head>
<body>
  <script src= "https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js" ></script>
  <script type= "text/javascript" >
  var callbackfunction = function(data) {
   alert( '接口返回的数据是:' + json.stringify(data));
  };
  </script>
  <script type= "text/javascript" src= "http://a/hello/map/getuser.json?callbackname=callbackfunction" ></script>
</body>
</html>

浏览器显示效果和上面一致。但此处需要注意的是, src 表示引入一个js文件,由于是直接调用接口,而接口返回的数据又刚好是一段js代码,故能被执行。另外,第二个 <script> 标签顺序不能颠倒,不然会出现 callbackfunction 函数找不到的情况.

工程代码地址 : https://github.com/smallercoder/jsonpdemo 。

最后总结下,解决跨域的方案有很多种,jsonp只是其中一种,具体情况需要具体分析。希望此文对你有帮助,谢谢阅读,欢迎github给颗 start ,么么哒!也希望大家多多支持我.

原文链接:https://juejin.im/post/5b1f8bc05188257d7541c2ce 。

最后此篇关于springboot+jsonp解决前端跨域问题小结的文章就讲到这里了,如果你想了解更多关于springboot+jsonp解决前端跨域问题小结的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com