SpringBoot解决解决CORS跨域

SpringBoot解决CORS跨域

关于跨域的概念问题,可以参数理解网络部分的三篇文章:

浏览器同源政策及其规避方法.md

XMLHttpRequest Level 2 使用指南.md

跨域资源共享 CORS 详解.md


该文章只是解决如何在SpringBoot中使用跨域访问的问题。

有两种方法:

一、使用@CrossOrigin注解设置单一访问路径的跨域问题

1、@CrossOrigin使用场景要求

  • jdk1.8+
  • Spring4.2+

2.使用@CrossOrigin注解

先通过源码看看该注解支持的属性:

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {

    String[] DEFAULT_ORIGINS = { "*" };

    String[] DEFAULT_ALLOWED_HEADERS = { "*" };

    boolean DEFAULT_ALLOW_CREDENTIALS = true;

    long DEFAULT_MAX_AGE = 1800;


    /**
     * 同origins属性一样
     */
    @AliasFor("origins")
    String[] value() default {};

    /**
     * 所有支持域的集合,例如"http://domain1.com"。
     * <p>这些值都显示在请求头中的Access-Control-Allow-Origin
     * "*"代表所有域的请求都支持
     * <p>如果没有定义,所有请求的域都支持
     * @see #value
     */
    @AliasFor("value")
    String[] origins() default {};

    /**
     * 允许请求头重的header,默认都支持
     */
    String[] allowedHeaders() default {};

    /**
     * 响应头中允许访问的header,默认为空
     */
    String[] exposedHeaders() default {};

    /**
     * 请求支持的方法,例如"{RequestMethod.GET, RequestMethod.POST}"}。
     * 默认支持RequestMapping中设置的方法
     */
    RequestMethod[] methods() default {};

    /**
     * 是否允许cookie随请求发送,使用时必须指定具体的域
     */
    String allowCredentials() default "";

    /**
     * 预请求的结果的有效期,默认30分钟
     */
    long maxAge() default -1;

}

如果你对这些属性的含义不是很明白,建议阅读下面的文章了解更多:

http://fengchj.com/?p=1888

下面举例在方法和Controller上使用该注解。

3.在Controller上使用@CrossOrigin注解

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

这里指定当前的AccountController中所有的方法可以处理http://domain2.com域上的请求,

4.在方法上使用@CrossOrigin注解

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin("http://domain2.com")
    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

在这个例子中,AccountController类上也有@CrossOrigin注解,retrieve方法上也有注解,Spring会合并两个注解的属性一起使用。

二、使用全局配置的方式解决跨域问题

除了细粒度基于注解的配置,你可能会想定义一些全局CORS的配置。这类似于使用过滤器,但可以在Spring MVC中声明,并结合细粒度@CrossOrigin配置。默认情况下所有的域名和GET、HEAD和POST方法都是允许的。

有两种方法,不过有一种是过时的了,先说过时的方式:

1.过时的

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

您可以轻松地更改任何属性,以及配置适用于特定的路径模式的CORS:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("http://domain2.com")
            .allowedMethods("PUT", "DELETE")
            .allowedHeaders("header1", "header2", "header3")
            .exposedHeaders("header1", "header2")
            .allowCredentials(false).maxAge(3600);
    }
}

如果你使用Spring Boot,你可以通过这种方式方便的进行配置。


还有一种使用匿名方式的配置

package com.wwj.helloworldquick.config;
// ....
@Configuration
public class MyCORS {
    //@Bean
    public WebMvcConfigurer corsConfigration() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                CorsRegistration corsRegistration = registry.addMapping("/**");
                corsRegistration.allowedOrigins("http://domain2.com");
                super.addCorsMappings(registry);
            }
        };
    }
}

2.基于XML的配置

这种方式的配置,不知道还有没有过时

<mvc:cors>
    <mvc:mapping path="/**" />
</mvc:cors>

这个配置和上面JAVA方式的第一种作用一样。

同样,你可以做更复杂的配置:

<mvc:cors>

    <mvc:mapping path="/api/**"
        allowed-origins="http://domain1.com, http://domain2.com"
        allowed-methods="GET, PUT"
        allowed-headers="header1, header2, header3"
        exposed-headers="header1, header2" allow-credentials="false"
        max-age="123" />

    <mvc:mapping path="/resources/**"
        allowed-origins="http://domain1.com" />

</mvc:cors>

3.现在常用的

package com.wwj.helloworldquick.config;

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;
import org.springframework.web.servlet.config.annotation.CorsRegistration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyCORS {

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();

        // 可以自行筛选
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");

        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        source.registerCorsConfiguration("/user/**", buildConfig());
        return new CorsFilter(source);
    }

}

三、ajax

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>demo</title>
        <script type="text/javascript" src="js/jquery-3.3.1.min.js" ></script>
    </head>
    <body>
        <input type="button" value="测试" onclick="ajaxloding()" />
        <div id="usermessage"></div>
        <script>
            var getdata=0;
            function ajaxloding(){
                $.ajax({
                    async:false,
                    type:"get",
                    url:"http://localhost:8080/api/finduser?id=1",
                    contentType: "application/x-www-form-urlencoded",
                    dataType: "json",
                    data: {},
                    success:function(result){
                        getdata=result.name
                    },
                    error: function (errorMsg) {
                        //请求失败时执行该函数
                        alert("请求数据失败!");
                    }
                });
                $("#usermessage").text(getdata)
            }
        </script>
    </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值