一、Web 开发经常会遇到跨域问题,解决方案有:jsonp,iframe,CORS 等等 CORS 与 JSONP 相比
1、 JSONP 只能实现 GET 请求,而 CORS 支持所有类型的 HTTP 请求。
2、 使用 CORS,开发者可以使用普通的 XMLHttpRequest 发起请求和获得数据,比起 JSONP 有更好的 错误处理。
3、 JSONP 主要被老的浏览器支持,它们往往不支持 CORS,而绝大多数现代浏览器都已经支持了 CORS
浏览器支持情况
Chrome 3+
Firefox 3.5+
Opera 12+
Safari 4+
Internet Explorer 8+
二、在 spring MVC 中可以配置全局的规则,也可以使用@CrossOrigin注解进行细粒度的配置。

方案一:全局方式支持CORS白名单

  • 如果有多个地址,那么就用一个for循环配置多个地址。
    1. @Configuration
    2. public class CustomCorsConfiguration {
    3. @Bean
    4. public WebMvcConfigurer corsConfigurer() {
    5. return new WebMvcConfigurerAdapter() {
    6. @Override
    7. public void addCorsMappings(CorsRegistry registry) {
    8. registry.addMapping("/api/**").allowedOrigins("http://localhost:8080");
    9. } };
    10. } }

方案二:全局方式支持CORS白名单

  • 如果有多个地址,那么就用一个for循环配置多个地址。 ```java /**
  • 全局设置 *
  • @author wujing / @Configuration public class CustomCorsConfiguration2 extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(“/api/*“).allowedOrigins(“http://localhost:8080“); } } ```

方案三:配置单个接口

  1. /**
  2. * @author wujing
  3. */
  4. @RestController
  5. @RequestMapping(value = "/api", method = RequestMethod.POST)
  6. public class ApiController {
  7. @CrossOrigin(origins = "http://localhost:8080")
  8. @RequestMapping(value = "/get")
  9. public HashMap<String, Object> get(@RequestParam String name) {
  10. HashMap<String, Object> map = new HashMap<String, Object>();
  11. map.put("title", "hello world");
  12. map.put("name", name);
  13. return map;
  14. } }

测试方法(一个特别简单的返回Json的RestController)

  1. /**
  2. * @author wujing
  3. */
  4. @RestController
  5. @RequestMapping("/api")
  6. public class ApiController {
  7. @RequestMapping(value = "/get")
  8. public HashMap<String, Object> get(@RequestParam String name) {
  9. HashMap<String, Object> map = new HashMap<String, Object>();
  10. map.put("title", "hello world");
  11. map.put("name", name);
  12. return map;
  13. } }

用于测试CORS的js

  • 用Chrome的devtool小工具即可测试
  1. $.ajax({
  2. url: "http://localhost:8081/api/get",
  3. type: "POST",
  4. data: {
  5. name: "测试" },
  6. success: function(data, status, xhr) {
  7. console.log(data);
  8. alert(data.name);
  9. } });

测试截图

不在白名单时报错,允许*则可以跨域读取Json资源。
【20180924】SpringBoot支持CORS - 图1

安全问题

  • 没有控制好白名单而允许*的话,会有json劫持问题。