Ajax 跨域解决(一)——SpringBoot学习

什么是跨域

在目前的前后端分离开发模式下,前端使用 Ajax 访问后端提供的接口获取数据,产生报错。

 

跨域发生的原因

1. 浏览器的限制

2. 发生跨域访问

3. 发送的是 XHR(XMLHttpRequst) 请求

三者同时发生,就会发生跨域问题

 

解决方式

因为是三者同时发生,才能发生跨域问题,因此针对三者,处理其中的一个即可。

 

首先是浏览器的限制,需要指定参数让浏览器不做校验,但方法不太合理,需要每个人都去做修改。其次是发送的请求不要是 XHR 类型的,解决方式是 JSONP 。最后是针对跨域,分为两点,一是让被调用方支持跨域,在响应头中添加参数,表示支持跨域访问,核心是支持跨域,二是让调用方在请求中使用代理,将从 A 域名发送到 B 的请求通过代理,让 B 认为是从本域名来的,核心是隐藏跨域。

 

具体解决方式

针对浏览器,通过命令行的方式启动,让其不要做跨域校验即可。

eg:chrome --disable-web-security

 

针对 XHR 方式,本身浏览器发送的是 json 请求,通过 jsonp 的方式,将其变为 js 的方式,核心是通过动态添加 script 的方式来封装了请求,从而解决跨域问题。

 

使用这种方式需要修改服务端的代码,修改方式如下:

@ControllerAdvice

public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice (

    public JsonpAdvice() {

        super("callback");

    }

}

 

前端通过制定 dataType 的方式来发送请求,如下所示

$.ajax({

    url:base+"/get1",

    dataType: "jsonp",

    jsonp: "callback2",

    cache: true,

    type:"post",

    success:function(json){

        result = json;
    }
})

但使用这种方式仍然是不好的方式,其有如下弊端

1. 需要服务器端改变代码,如果涉及调用第三方接口,根本无法完成;

2. 只支持 GET 请求,在真是的业务场景中十分受限;

3. 因为改变了请求的类型,从 XHR 变为了 js 方式,因此 XHR 的很多优良特性无法使用。

 

因此,解决跨域问题最好的方式还是通过解决跨域访问来解决,使用服务器端支持跨域或调用端隐藏跨域来解决。

 

调用方解决跨域(支持跨域)的3种解决方式

1. 服务器端实现

2. Nginx 配置

3. Apache 配置

 

使用 Filter 来实现

通过过滤器在所有请求的 Response 中添加字段来支持跨域访问。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest req = (HttpServletRequest) request;

    HttpServletResponse res = (HttpServletResponse) response;

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

    if (!StringUtils.isEmpty(origin)){ // 动态添加访问地址,使得所有的域名都可以跨域访问

        res.addHeader("Access-Control-Allow-Origin",origin);

    }

    String headers = req.getHeader("Access-Control-Request-Headers");

    if (!StringUtils.isEmpty(headers)){ // 动态添加自定义访问头

        res.addHeader("Access-Control-Allow-Headers",headers);

    }

    res.addHeader("Access-Control-Allow-Methods","*");

    res.addHeader("Access-Control-Max-Age","3600");

    res.addHeader("Access-Control-Allow-Credentials","true");

    chain.doFilter(request,response);

}



@Bean

FilterRegistrationBean registrationBean(){

    FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean();

    filterRegistrationBean.addUrlPatterns("/*");

    filterRegistrationBean.setFilter(new CrosFilter());

    filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);

    filterRegistrationBean.setName("Ajax");

    return filterRegistrationBean;

}

 

 

被调用方解决跨域(隐藏跨域)的解决方式

在 Spring 框架中的解决方式:在需要的类或方法上加上注解, @CrossOrigin

 

Nginx 配置

Apache 配置

Nginx 和 Apache 的解决方式因为涉及到其两个框架的方式,因为还没有深入了解过,所以在这没有叙述,以后深入学习过后,再详细编写。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
跨域是指在浏览器中,一个网页的脚本试图访问不同源(域、协议、端口)的资源时产生的安全限制。浏览器为了保护用户信息安全,会阻止跨域请求。 解决跨域问题有多种方法,以下是一些常见的解决方案: 1. JSONP(仅支持GET请求):通过在页面中动态创建`<script>`标签,向目标服务器请求数据。服务器返回JSONP格式的数据,浏览器解析并执行回调函数。 2. CORS(跨域资源共享):服务端设置响应头部,允许指定的源进行跨域请求。在Spring Boot中,可以通过添加`@CrossOrigin`注解来实现。 3. 代理服务器:配置一个同源的代理服务器,将浏览器的请求转发到目标服务器,然后将响应返回给浏览器。这种方式需要在服务器端进行配置。 4. WebSocket:使用WebSocket协议进行通信,WebSocket不受同源策略限制。 对于Spring Boot应用解决跨域问题,可以使用CORS方式。在控制器类或方法上添加`@CrossOrigin`注解即可实现跨域请求的支持。例如: ```java @RestController @CrossOrigin(origins = "http://example.com") public class MyController { // ... } ``` 上述代码表示允许来自"http://example.com"域的跨域请求。你可以根据实际情况修改`origins`参数,甚至使用`"*"`来允许所有来源的请求。 同时,你也可以在全局配置文件(如`application.properties`或`application.yml`)中添加以下配置来实现全局跨域支持: ```yaml spring: cors: allowed-origins: http://example.com ``` 这样配置后,所有的请求都会允许来自"http://example.com"域的跨域请求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值