嘎里三分熟
  • 首页
  • JMusic
  • TSBay
  • 常用工具
  • About Me
  • 留言板
一行代码一世浮生
  1. 首页
  2. Java基础
  3. 正文

解决跨域请求问题:jsonp & CORS

2017年12月10日 3304点热度 5人点赞 1条评论

一、背景

    跨域问题是发生在前端的问题,是指前端在访问不同域名或端口或协议的地址时候,由于浏览器的同源策略的约束,所以会产生跨域问题。

    如下 ajax 请求不同端口的地址,就会出现 403:

    $.ajax({    
      type: "get",
      url: "http://localhost:9091/rest/jsonp",
      dataType: "json",
      success: function(val) {
           console.log(val);
      }
    });

        jsonp01.png

二、jsonp 解决跨域

    此法很简单,前端和后端分别做点小改动就可。

    1)前端修改

        就是将 ajax 请求的 datatype 设置成 jsonp 即可,如下:

            jsonp02.png

    2)后端修改

        后端只需要添加配置类即可,如下(此处是 springboot):

        /**        
         * Created by Jet on 2017/12/10.
         */
        @ControllerAdvice
        @SpringBootConfiguration
        public class JsonAdvice extends AbstractJsonpResponseBodyAdvice{
            public JsonAdvice(){
                // 这样如果请求中带 callback 参数,Spring 就知道这个是 jsonp 的请求了
                super("callback");
            }
        }

    3)效果

        jsonp03.png

        地址后面会自动生成 callback 参数,当然,这就意味着你也可以手动定义 callback 函数来指定回调函数。

    4)原理

        其实底层就是通过动态创建 <script> 标签,然后把 src 指向服务端地址,而这个地址后面的参数 callback 就是回调函数,

        最主要的其实是因为: <script>标签不受同源策略的约束,

    5)弊端

        此法很巧妙,很巧妙,但是 <script> 标签是只能发生 get 请求的,所以,jsonp 只能用来解决 get 请求的跨域问题。

三、CORS 解决跨域

    1)简述

        既然 jsonp 有弊端,那么 post 等其余请求该如何解决跨域问题呢?很简单,此处介绍 CORS。

        CORS:Cross-Origin Resource Sharing

    2)浏览器支持

        但是对浏览器有版本的要求,如下(其实目前大部分 web 应用都要求只是 IE8 了):

    • Chrome 3+

    • Firefox 3.5+

    • Opera 12+

    • Safari 4+

    • Internet Explorer 8+

    3)前端实现

    $.ajax({    
        type: "post",
        url: "http://localhost:9091/rest/jsonp",
        dataType: "json", 
        crossDomain: true, // 使用跨域请求
        xhrFields: {
            withCredentials: true // 把 cookie 带过去了,不然我们连 session 都没法维护
        },
        success: function(val) {
            console.log(val);
        }
    });

        如上,要注意 withCredentials 设置为 true,将 cookie 带过去,否则会载坑。

    4)后端实现

        后端添加一条配置即可:

    @Configuration    
    public class WebConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**")
                            //放行哪些原始域
                            .allowedOrigins("*")
                            //是否发送Cookie信息
                            .allowCredentials(true)
                            //放行哪些原始域(请求方式)
                            .allowedMethods("GET","POST", "PUT", "DELETE")
                            //放行哪些原始域(头部信息)
                            .allowedHeaders("*")
                            //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
                            .exposedHeaders("Header1", "Header2");
        }
    }

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: CORS java jsonp 同源策略 跨域
最后更新:2018年09月27日

GoldenJet

爱折腾技术的90后漫威小死忠程序员一枚

点赞
< 上一篇
下一篇 >

文章评论

取消回复

通过电子邮件订阅博客

分类目录
  • BootStrap (2)
  • Bug集中营 (6)
  • Java web (3)
  • JavaScript (7)
  • Java基础 (17)
  • Java工具 (5)
  • Linux (3)
  • Python (3)
  • SpringBoot (14)
  • Spring基础 (8)
  • thymeleaf (1)
  • 娱乐 (3)
  • 小谈 (2)
  • 常用工具 (7)
  • 技术分析集 (5)
  • 技能 (10)
  • 源码 (4)
  • 科普类 (1)
  • 算法 (9)
  • 踩坑记 (5)
文章归档
  • 2020年11月 (1)
  • 2020年7月 (1)
  • 2020年4月 (2)
  • 2020年3月 (1)
  • 2020年1月 (1)
  • 2019年11月 (1)
  • 2019年10月 (1)
  • 2019年9月 (1)
  • 2019年8月 (1)
  • 2019年7月 (2)
  • 2019年5月 (2)
  • 2019年4月 (2)
  • 2019年3月 (3)
  • 2019年2月 (2)
  • 2019年1月 (2)
  • 2018年12月 (2)
  • 2018年11月 (3)
  • 2018年10月 (3)
  • 2018年9月 (2)
  • 2018年8月 (3)
  • 2018年7月 (2)
  • 2018年5月 (1)
  • 2018年4月 (3)
  • 2018年3月 (2)
  • 2018年2月 (3)
  • 2018年1月 (5)
  • 2017年12月 (2)
  • 2017年11月 (3)
  • 2017年10月 (1)
  • 2017年9月 (1)
  • 2017年8月 (1)
  • 2017年7月 (7)
  • 2017年6月 (5)
  • 2017年5月 (1)
  • 2017年4月 (2)
  • 2017年3月 (4)
  • 2017年2月 (2)
小伙伴友链
  • 前端驿站

COPYRIGHT © 2017-2023 嘎里三分熟. ALL RIGHTS RESERVED.

浙ICP备17005575号-1

浙公网安备 33010802009043号