Skip to content

跨域问题

TIP

是指在浏览器中进行跨域请求时所遇到的限制。同源策略是浏览器的一种安全策略,它限制了一个页面中的脚本只能访问同源(相同协议、域名和端口)的资源,而不能直接访问其他域名下的资源。

跨域请求一般分为以下几种情况:

  1. 不同域名之间的跨域请求:从www.hfxtsk.cn的页面向wiki.hfxtsk.cn发送请求。
  2. 不同子域之间的跨域请求:从wiki.hfxtsk.cn的页面向git.hfxtsk.cn发送请求。
  3. 不同协议之间的跨域请求:从http://hfxtsk.cn的页面向https://hfxtsk.cn发送请求。
  4. 不同端口之间的跨域请求:从http://hfxtsk.cn的页面向http://hfxtsk.cn:8080发送请求。

SpringBoot工程

覆写WebMvcConfigurer接口的addCorsMappings方法

java
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 所有接口
                .allowCredentials(true) // 是否发送 Cookie
                .allowedOriginPatterns("*") // 支持域
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 支持方法
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
}
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 所有接口
                .allowCredentials(true) // 是否发送 Cookie
                .allowedOriginPatterns("*") // 支持域
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 支持方法
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
}

通过CorsFilter解决跨域

java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class MyCorsFilter {
    @Bean
    public CorsFilter corsFilter() {
        // 1.创建 CORS 配置对象
        CorsConfiguration config = new CorsConfiguration();
        // 支持域
        config.addAllowedOriginPattern("*");
        // 是否发送 Cookie
        config.setAllowCredentials(true);
        // 支持请求方式
        config.addAllowedMethod("*");
        // 允许的原始请求头部信息
        config.addAllowedHeader("*");
        // 暴露的头部信息
        config.addExposedHeader("*");
        // 2.添加地址映射
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**", config);
        // 3.返回 CorsFilter 对象
        return new CorsFilter(corsConfigurationSource);
    }
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class MyCorsFilter {
    @Bean
    public CorsFilter corsFilter() {
        // 1.创建 CORS 配置对象
        CorsConfiguration config = new CorsConfiguration();
        // 支持域
        config.addAllowedOriginPattern("*");
        // 是否发送 Cookie
        config.setAllowCredentials(true);
        // 支持请求方式
        config.addAllowedMethod("*");
        // 允许的原始请求头部信息
        config.addAllowedHeader("*");
        // 暴露的头部信息
        config.addExposedHeader("*");
        // 2.添加地址映射
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**", config);
        // 3.返回 CorsFilter 对象
        return new CorsFilter(corsConfigurationSource);
    }
}

通过@CrossOrigin注解解决跨域

java
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/hello")
@CrossOrigin
public class HelloController {
    @GetMapping
    public String getHi() {
        return "Hello World";
    }
}
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/hello")
@CrossOrigin
public class HelloController {
    @GetMapping
    public String getHi() {
        return "Hello World";
    }
}

Nginx配置CORS解决跨域

允许全部域名

bash
server {
    
    location / {
        #允许 所有头部 所有域 所有方法
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Allow-Methods' '*';
        #OPTIONS 直接返回204
        if ($request_method = 'OPTIONS') {
            return 204;
        }
    }
}
server {
    
    location / {
        #允许 所有头部 所有域 所有方法
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Allow-Methods' '*';
        #OPTIONS 直接返回204
        if ($request_method = 'OPTIONS') {
            return 204;
        }
    }
}

允许指定域名

bash
map $http_origin $corsHost {
    default 0;
    "~https://hfxtsk.cn" https://hfxtsk.cn;
    "~https://marsgis.cn" https://marsgis.cn;
    "~https://baidu.com" https://baidu.com;
}
server {
    location / {
        #允许 所有头部 所有$corsHost域 所有方法
        add_header 'Access-Control-Allow-Origin' $corsHost;
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Allow-Methods' '*';
        #OPTIONS 直接返回204
        if ($request_method = 'OPTIONS') {
            return 204;
        }
    }
}
map $http_origin $corsHost {
    default 0;
    "~https://hfxtsk.cn" https://hfxtsk.cn;
    "~https://marsgis.cn" https://marsgis.cn;
    "~https://baidu.com" https://baidu.com;
}
server {
    location / {
        #允许 所有头部 所有$corsHost域 所有方法
        add_header 'Access-Control-Allow-Origin' $corsHost;
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Allow-Methods' '*';
        #OPTIONS 直接返回204
        if ($request_method = 'OPTIONS') {
            return 204;
        }
    }
}