• 跨域


    序:这篇随笔是看了“晓风轻老师的ajax跨域完全讲解”的视频之后的笔记。

    一、产生跨域的条件
      (一)浏览器同源策略的限制
      (二)请求跨域(协议、域名、端口不同)
      (三)请求的类型是XMLHttpRequest
      同时符合上面三条,才会发生跨域问题。

    二、解决思路
      (一)改浏览器设置,使浏览器支持
        在Chrome浏览器安装目录执行 chrome --disable-web-security --user-data-dir=g: emp3
        我测试失败了,有兴趣的同学可以试试,教程链接

      (二)JSONP(请求类型从xhr变成script)
        1.前端JSONP

    $.ajax({  
        url: '',  
        dataType: 'jsonp',  
        success: function(json) {  
            result = json;
            }
        });
    JSONP-jQuery

        这是使用的是jQuery,虽然jQuery把JSONP看做是ajax,其实真的不是一回事,具体可参考《说说JSON和JSONP...

        2.后台同步支持

    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice;
    
    @ControllerAdvice
    public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
    
        public JsonpAdvice() {
            super("callback");
        }
    }
    JSONP-springboot

        因为教程是基于springboot,所以这是springboot上的一种方法,但是这种方式在spingboot2.0上已经无法使用了!!!

        虽然方法已经过时了,但总体的思路是不变的,就是在后端返回数据时,不直接返回JSON,而是返回的javascript代码。

        下面是我按照JSONP协议实现的代码

    <script type="text/javascript">
    var afterJsonp = function(data){
        alert('经过jsonp的data是:' + data.data);
    };
    var url = "http://127.0.0.1:8080/test/testJsonp?data=something&callback=afterJsonp";
    var script = document.createElement('script');
    script.setAttribute('src', url);
    document.getElementsByTagName('head')[0].appendChild(script);
    </script>
    JSONP-前端
    @GetMapping("/testJsonp")
    public String testJsonp(String data,String callback) {
        //简单的处理下传参
        data += " after jsonp";
        String ret = callback + "({"data":""+data+""})";
        return ret;
    }
    JSONP-后端

        JSONP的弊端:服务器需要改代码(加拦截器、加注解或者别的什么方式)、只支持GET、不是XHR

      (三)支持跨域(被调用方支持跨域/调用方隐藏跨域)
        1.被调用方解决-支持跨域
          (1)服务器实现-通过filter解决

    @SpringBootApplication
    public class AjaxserverApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(AjaxserverApplication.class, args);
        }
    
        @SuppressWarnings({ "rawtypes", "unchecked" })
        @Bean
        public FilterRegistrationBean registerFilter() {
            FilterRegistrationBean bean = new FilterRegistrationBean();
            bean.addUrlPatterns("/*");
            bean.setFilter(new CrosFilter());
            return bean;
        }
    
    }
    Filter添加
    public class CrosFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            HttpServletResponse res = (HttpServletResponse) response;
            res.addHeader("Access-Control-Allow-Origin", "*");
            res.addHeader("Access-Control-Allow-Methods", "*");
            chain.doFilter(request, response);
        }
    
    }
    Filter实现

          (2)Nginx 这里直接放视频教程

          (3)Apache 这里直接放教程视频

          (4)如果是spring框架,只需要在类或方法上加注解“@CrossOrigin”

        2.调用方解决-隐藏跨域(通过方向代理实现)
          (1)Nginx 这里直接放视频教程

          (2)Apache 这里直接放视频教程

    三、额外知识点
      (一)简单请求和非简单请求

    同时满足下面两点就是简单请求
        1.请求方法是以下三种方法之一:HEAD、GET、POST
        2.HTTP的头信息不超出以下几种字段:
        Accept
        Accept-Language
        Content-Language
        Last-Event-ID
        Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

    这里推荐下阮一峰老师的《跨域资源共享 CORS 详解》,对应的是上面的“服务器实现-通过filter解决”这种方式。

    说点题外话,距离上篇随笔,已经过去了快两年,这两年的学习和工作就像随笔一样,停滞不前,有时候都有想放弃“写bug”的冲动。唉,不够努力,只会被时代抛弃...

  • 相关阅读:
    2021.1.11
    2021.1.10(每周总结)
    2021.1.9
    2021.1.8
    2021.1.7
    构建之法阅读笔记01
    [java] XML DTD XSD
    详解 泛型 与 自动拆装箱
    详解 正则表达式
    详解 LinkedHashMap
  • 原文地址:https://www.cnblogs.com/xiancheng/p/11374251.html
Copyright © 2020-2023  润新知