参考资料

  1. 阮一峰_CORS 通信
  2. 路人甲_跨域问题详解

  • 所有的跨域方案都是修改响应头,向响应头中添加浏览器所要求的数据,进而实现跨域。
  • CorsFilterWebMvcConfigurer属于全局 CORS 配置,@CrossOrigin属于局部 CORS配置。
  • 如果使用了局部跨域是会覆盖全局跨域的规则,所以可以通过 @CrossOrigin 注解来进行细粒度更高的跨域资源控制。


前期准备

  • 前台html,使用Live Server运行,url为http://127.0.0.1:5500/跨域测试.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>跨域测试</title>
    </head>
    <body>
        <button id="btn">发送Ajax请求</button>
    </body>
    <script src="https://cdn.staticfile.org/jquery/3.6.0/jquery.js"></script>
    <script>
    
        // 封装Ajax请求
        function doAjax(url, data, callback) {
            $.ajax({
                url: url,
                type: 'POST',
                data: JSON.stringify(data),
                contentType : 'application/json;charset=utf-8',
                dataType: 'json',
                success: function (data, status, xhr) {
                    if (!!callback) {
                        callback(data);
                    }
                },
                error: function (xhr, textStatus, errorMessage) {
    
                    if (xhr.status !== 400) {
                        console.log(xhr);
                    }
    
                    const data = xhr.responseJSON;
                    callback(data);
                }
            });
        }
    
        $("#btn").click(() => {
    		
    		// 后台接口
            const url = "http://localhost:8080/test8/CORS_Test";
            const paramObject = {
                id: "100",
                name: "jmw"
            };
            doAjax(url, paramObject, function(data) {
                console.log(data);
            })
        });
    </script>
    </html>
    
  • 后台实体类

    import lombok.Data;
    
    @Data
    public class Test8Form {
    
        private String id;
        private String name;
    }
    
  • 后台Controller层

    import com.example.jmw.form.Test8Form;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @Controller
    @RequestMapping("/test8")
    public class Test8Controller {
        
        @PostMapping("/CORS_Test")
        @ResponseBody
        public Map<String, String> groupSequenceProvider(@RequestBody Test8Form form) {
    		
    		// 将前台跨域请求提交的数据,放到map中,然后再返回给前台
            HashMap<String, String> map = new HashMap<>();
            map.put("idFromWeb", form.getId());
            map.put("nameFromWeb", form.getName());
    
            return map;
        }
    }
    
  • 没有配置允许跨域访问之前

    在这里插入图片描述


1. CorsFilter实现全局跨域配置

在任意配置类,返回一个 新的 CorsFIlter Bean,并添加映射路径和具体的CORS配置路径。

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 CustomCorsConfiguration {

    // 导入Cors的过滤器,在配置文件中进行配置
    @Bean
    public CorsFilter corsFilter(){

        // 初始化cors配置对象
        CorsConfiguration configuration = new CorsConfiguration();

        // 设置允许跨域的域名,如果允许携带cookie的话,路径就不能写*号, *表示所有的域名都可以跨域访问
        configuration.addAllowedOrigin("http://127.0.0.1:5500");
        // 设置跨域访问可以携带cookie
        configuration.setAllowCredentials(true);
        // 允许所有的请求方法 ==> GET POST PUT Delete
        configuration.addAllowedMethod("*");
        // 允许携带任何头信息
        configuration.addAllowedHeader("*");

        // 初始化cors配置源对象
        UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();

        // 给配置源对象设置过滤的参数
        // 参数一: 过滤的路径 == > 所有的路径都要求校验是否跨域
        // 参数二: 配置类
        configurationSource.registerCorsConfiguration("/**", configuration);

        // 返回配置好的过滤器
        return new CorsFilter(configurationSource);
    }
}

⏹效果
在这里插入图片描述


2. 重写WebMvcConfigurer实现全局跨域配置

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        	registry.addMapping("/**")
            // 是否发送Cookie
            .allowCredentials(true)
            // 放行哪些原始域
            .allowedOrigins("*")
            // 放行哪些请求方式
            .allowedMethods("GET", "POST", "PUT", "DELETE")
            // 放行哪些原始请求头部信息
            .allowedHeaders("*")
            // 暴露哪些头部信息
            .exposedHeaders("*");
    }
}

⏹效果

在这里插入图片描述


3. @CrossOrigin局部方法跨域

  • 在控制器(类上)上使用注解@CrossOrigin,表示该类的所有方法允许跨域。

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @Controller
    @RequestMapping("/test8")
    @CrossOrigin(origins = "http://127.0.0.1:5500")
    public class Test8Controller {
        
        @PostMapping("/CORS_Test")
        @ResponseBody
        public Map<String, String> groupSequenceProvider(@RequestBody Test8Form form) {
    
            HashMap<String, String> map = new HashMap<>();
            map.put("idFromWeb", form.getId());
            map.put("nameFromWeb", form.getName());
    
            return map;
        }
    }	
    

    ⏹效果

    在这里插入图片描述

  • 在方法上使用注解@CrossOrigin,仅允许该方法跨域

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @Controller
    @RequestMapping("/test8")
    public class Test8Controller {
    
        @CrossOrigin(origins = "http://127.0.0.1:5500")
        @PostMapping("/CORS_Test")
        @ResponseBody
        public Map<String, String> groupSequenceProvider(@RequestBody Test8Form form) {
    
            HashMap<String, String> map = new HashMap<>();
            map.put("idFromWeb", form.getId());
            map.put("nameFromWeb", form.getName());
    
            return map;
        }
    }
    

    ⏹效果

    在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐