AJAX跨域问题

什么是AJAX跨域问题

       现在的开发是前后台完全分离的趋势发展,那么什么是AJAX跨域问题?简单来说,你在前台调用后台服务接口,如果这个接口不是同一个域,就会产生跨域问题。

为什么会发生AJAX跨域问题?

1. 浏览器限制,说白了也就是浏览器多管闲事。

2. 跨域:http://localhost:8080  http://localhost:8081 这是两个不同的域

3. XHR(XMLHttpRequest)请求

解决思路

       浏览器限制:指定参数,指定参数让浏览器不去做这个限制(不推荐)

       XHR:修改发送的数据类型JSONP(现在少用)

       跨域:被调用方修改代码,支持跨域

                调用方修改代码,支持跨域

解决方案

1. 命令行参数启动浏览器,增加参数,比如—disable-web-security,禁止浏览器检查

2. JSONP如何解决跨域

JSONP是什么?

使用JSONP服务器后台要改动吗?

          后台需要改动->使用jsonp后台解决起来比较简单,首先我们改的是服务器后台代码。我们增加一个controller层的切面,ControllerAdvice但是,在使用的时候AbstractJsonpResponseBodyAdvice 这个类找不到,很苦恼应该是我是用的版本不正确,上面是我记录的源代码,仅供参考。

       JSONP有什么弊端?

                  服务器需要改动代码支持;只支持GET;发送的不是XHR请求。

1. 跨域

最常见的Java2ee架构

 

       跨域解决方向->被调用方解决、调用方解决

      被调用方解决:这是一种支持跨域的的解决思路,是基于http协议关于跨域方面的规定,在响应头里增加指定的字段,告诉浏览器允许跨域,修改的是被调用方http服务器。

       调用方解决:这是基于隐藏跨域的的解决思路,跨域请求不会直接从调用方发送到被调用方,而是从中间的http服务器转发过去,修改的是调用方服务器。

             被调用方解决-支持跨域

   两个地方增加响应头:中间HTTP(APACHE/NGINX)服务器、应用服务器

          服务器端实现

          NGINX配置

          APACHE配置

(1)被调用方-Filter解决方案

跨域请求:

本域(非跨域)请求:

        对比跨域和非跨域请求发现:跨域请求的请求头里多了一个字段:Origin:http://localhost:8081/

        当浏览器发现这个请求是跨域的时候,就会多出这个字段,请求头里增加当前域的信息的字段,然后等请求返回来,浏览器就会检查响应头里有没有允许跨域的信息,如果没有,它就会报错。

(2)Filter代码实现

  springboot中filter的用法 :一、在spring的应用中我们存在两种过滤的用法,一种是拦截器、另外一种当然是过滤器。我们这里介绍过滤器在springboot的用法,在springmvc中的用法基本上一样,只是配置上面有点区别。二、filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).

       修改服务端的代码:在springboot中增加一个filter,增加filter的方法是注册一个FilterRegistrationBean。


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class AjaxserverApplication {

    public static void main(String[] args) {
        SpringApplication.run(AjaxserverApplication.class, args);
        System.out.println("项目启动...");
    }

    @Bean
   public FilterRegistrationBean registerFilter() {

      FilterRegistrationBean bean = new FilterRegistrationBean();

      bean.addUrlPatterns("/*");
      bean.setFilter(new CrosFilter());

      return bean ;
   }

}

        在doFilter中增加响应头,


import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CrosFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletResponse res = (HttpServletResponse) servletResponse;

        //指定允许域
        res.addHeader("Access-Control-Allow-Origin", "http://localhost:8081");
        //指定允许的方法
        res.addHeader("Access-Control-Allow-Methods", "GET");
//        //允许所有域
//        res.addHeader("Access-Control-Allow-Origin", "*");
//        //允许所有方法
//        res.addHeader("Access-Control-Allow-Methods", "*");

        //完整filter链
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

      刷新一下,下面是添加Filter后的响应头,跨域问题初步得到了解决。

(2)简单请求和非简单请求

       浏览器在发送跨域请求时会先判断请求是否是简单请求,如果是简单请求就会先执行,后判断,如果是非简单请求,它就会先发送OPTIONS预检查命令,检查通过之后,才会将跨域请求发送出去。

(3)带Cookie的跨域

   带cookie的跨域,Accss-Control-Allow-Origin:*,不能是“*”,必须写具体的域名。

   发送的cookie是被调用方的cookie,而不是调用方的cookie。

(4)被调用方解决跨域-nginx/apache解决方案

      虚拟主机:多个域名指向同一个服务器,服务器根据不同的域名,把请求转到不同的应用服务器。

      在被调用方配置NGINX/APACHE服务器。

(5)被调用方-SPRING框架解决方案

       在controller类上(或者方法上)加注解:

(6)调用方解决-隐藏跨域

       隐藏跨域的解决思路:跨域请求经过调用方的http服务器反向代理转发到被调用方的服务器,在浏览器上看不到任何跨域请求。

       什么是反向代理:简单来说访问同一个域名的两个不同URL,最后回去到两个不同服务器。

在调用方配置NGINX/APACHE服务器。

4.总结

这是我在学习跨域时做的笔记,通过学习,理解了跨域问题,仅供参考,欢迎留言评论。

这是讲解跨域问题的课程链接地址https://www.imooc.com/learn/947

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值