1. 首先要理解的是什么是跨域

同源策略:是指协议、域名、端口都要一致,任何一个不对都会产生跨域

浏览器发送的请求与当前正在访问的页面的协议不同,端口不同,域名不同,子域名不同都会造成跨域问题的发生,要注意的是这个是浏览器的同源策略造成的

2. 如果产生跨域问题是怎样的效果?

可以看到下图,发送请求成功,成功进了后台的接口,并且前端也看到响应返回200了,但是这个请求却爆红。

redis如何做异地双活_Access

redis如何做异地双活_服务器_02

而且无法加载期响应数据

redis如何做异地双活_运维_03

控制台也会提示出现跨域问题

redis如何做异地双活_运维_04

3.解决跨域问题(我后台用的是Java语言开发的)

这个时候就需要在后端给响应头(respond head)加上一些参数来告知浏览器当前这个跨域请求是合法的,允许他加载,允许他加载的方式有很多种,可以用过滤器或者拦截器, 或者也可以用nginx反向代理服务器,修改它的配置文件,让respond head中加上一些参数就行

我分别列举一下这些参数的含义和所代表的值吧

  • Access-Control-Allow-Origin
    必填字段,取值可以是请求时Origin字段的值,也可以是*,表示接受任意域名的请求。
  • Access-Control-Allow-Methods
    必填字段,取值是逗号分隔的一个字符串,设置服务器支持的跨域请求的方法。注意为了避免多次OPTIONS请求,返回的是所有支持的方法,逗号分隔。
  • Access-Control-Allow-Headers
    可选字段,CORS请求时默认支持6个基本字段,XMLHttpRequest.getResponseHeader()方法:
    Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。
    如果需要支持其他Headers字段,必须在Access-Control-Allow-Headers里面指定。
  • Access-Control-Allow-Credentials
    可选字段,布尔值类型,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中;如果设为true,即表示服务器允许在请求中包含Cookie, 一起发给服务器。
  • Access-Control-Max-Age
    可选字段,用来指定预检请求的有效期,单位为秒,在此期间不用发出另一条预检请求,不指定时即使用默认值,Chrome默认5秒。
    常用浏览器有不同的最大值限制,Firefox上限是24小时 (即86400秒),Chrom是10分钟(即600秒)。
    注意Access-Control-Max-Age设置针对完全一样的url,当url包含路径参数时,其中一个url的Access-Control-Max-Age设置对另一个url没有效果。
然后上代码(我用的是拦截器实现的)

这里先实现写一个拦截器

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class CorsInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x_requested_with,x-requested-with,Authorization,Content-Type,token");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        return true;
    }
}

然后写一个配置类,配置加载一下这个拦截器

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Author china007cxd
 * @Time : 2022/11/7 17:08
 **/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Bean
    public CorsInterceptor corsInterceptor() {
        return new CorsInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(corsInterceptor())
                .addPathPatterns("/**");
    }

}

这样就完成了,然后重新启动一下后台服务器

4. 完成

然后可以看效果,发现请求也不爆红了,控制台信息也没了,响应头中也有了我拦截器中加上的参数,响应体中的数据也能正常加载出来了

redis如何做异地双活_Access_05

5. 总结

以上说了这么多,跨域的问题本质上是浏览器的同源策略造成的,如果要解决跨域问题,就需要告诉浏览器这个跨域请求是合法的,是可以加载的,而如何告诉浏览器呢?这就可以通过后台代码或者nginx配置,在响应头中加上这些参数,浏览器看到你响应头中的这些参数后就会明白这个跨域请求合法从而正常加载了。

大家也可以去看看市面上的其他网站,F12看在他们的响应头中基本都会有这些参数(必填的那几个),以此来解决跨域问题!