解决ajax跨域几种方式

发生跨域问题的原因:

  • 浏览器的限制,出于安全考虑。前台可以正常访问后台,浏览器多管闲事报跨域问题,但其实前台已经访问到后台了。

  • 跨域,协议、域名、端口任何一个不一样浏览器就认为是跨域。

  • XHR(XMLHttpRequest)请求,因为ajax是XHR请求,浏览器就会捕捉跨域问题。

解决思路:

  • 让浏览器不做限制,指定参数,让浏览器不做校验,但该方法不太合理,它需要每个人都去做改动。

  • 不要发出XHR请求,这样就算是跨域,浏览器也不会报错,解决方案是JSONP,通过动态创建一个script,通过script发出请求。

  • 在跨域的角度:一种是被调用方修改代码,加上字段,告诉浏览器,支持跨域,支持调用

  • 通过nginx代理方式,在a域名里面的的请求地址使用代理指定到b域名。

跨域解决方案:

  • 被调用方解决:在请求响应头增加指定字段,告诉浏览器允许调用。这种解决方案的请求是直接从浏览器发送的。(服务器端实现、NGINX配置Apache配置)

  • 调用方解决:这是隐藏跨域的解决法案。这种跨域请求不是直接从浏览器发送的,而是从中间的http服务器转发过去的。

设置浏览器不做限制:

  • 可以使用everyting软件搜索浏览器的全路径,使用dos切换到此路径下 cd C:\Users\Administrator\AppData\Local\Google\Chrome\Application

  • 输入 chrome --disable-web-security --user-data-dir=g:\temp3(g磁盘 temp3数据存储文件可随便创建)

使用jsonp解决:

  • Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。为什么我们从不同的域(网站)访问数据需要一个特殊的技术(JSONP )呢?这是因为同源策略。同源策略,它是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略。

    扫描二维码关注公众号,回复: 8109557 查看本文章
  • 前端ajax方法请求设置 dataType: "jsonp"jsonp: "callback"cache: true

  • 后台需要增加JsonpAdvice 类

  • jsonp只支持GET
  • 服务器需要改动代码
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
    public JsonpAdvice() {
        // TODO Auto-generated constructor stub
        // 这的名称需要和ajax中jsonp: "callback"设置的一样
        super("callback");
    }
}

 

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>跨域</title>
    <script src="jquery-1.11.3.js"></script>
    <link rel="stylesheet" type="text/css" href="jasmine-2.8.0/jasmine.css">
    <script src="jasmine-2.8.0/jasmine.js"></script>
    <script src="jasmine-2.8.0/jasmine-html.js"></script>
    <script src="jasmine-2.8.0/boot.js"></script>
</head>

<body>
    <script>
        function get1() {
                $.getJSON("http://localhost:8080/test/get1").then(function (result) {
                    console.log(result);
                });
            }
            // 每一个测试用例的超时时间
        jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
         // 请求的接口的前缀 // http://localhost:8080/test
        var base = "/ajaxserverapache";
         //测试模块
        describe("跨域", function () {// 测试方法
            it("jsonp请求", function (done) {
                // 服务器返回的结果
                var result;
                $.ajax({
                    url: base + "/get1",
                    dataType: "jsonp",
                    jsonp: "callback",
                    cache: true,
                    success: function (json) {
                        result = json;
                    }
                });
                // 由于是异步请求,需要使用setTimeout来校验
                setTimeout(function () {
                    expect(result).toEqual({
                        "data": "get1 ok"
                    });

                    // 校验完成,通知jasmine框架
                    done();
                }, 100);
            });
        });
    </script>
</body>

</html>

filter解决方案(被调用方):

  • 在springBoot启动类中设置filter类过滤

  • 设置具体的过滤参数信息

@SpringBootApplication
public class AjaxserverApplication {
    public static void main(String[] args) {
        SpringApplication.run(AjaxserverApplication.class, args);
    }

    @Bean
    public FilterRegistrationBean registerFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.addUrlPatterns("/*");
        //  设置自定义的filter类
        bean.setFilter(new CrosFilter());
        return bean;
    }
}
public class CrosFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        HttpServletResponse res = (HttpServletResponse) response;

        HttpServletRequest req = (HttpServletRequest) request;

        String origin = req.getHeader("Origin");

        if (!org.springframework.util.StringUtils.isEmpty(origin)) {
            //带cookie的时候,origin必须是全匹配,不能使用*
            res.addHeader("Access-Control-Allow-Origin", origin);
        }

        res.addHeader("Access-Control-Allow-Methods", "*");
        String headers = req.getHeader("Access-Control-Request-Headers");

        // 支持所有自定义头
        if (!org.springframework.util.StringUtils.isEmpty(headers)) {
            res.addHeader("Access-Control-Allow-Headers", headers);
        }
        res.addHeader("Access-Control-Max-Age", "3600");
        // enable cookie
        res.addHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
}

猜你喜欢

转载自www.cnblogs.com/haha66/p/12004178.html