跨域
什么是跨域,跨域是指从不同地址或者端口发送数据获取请求,被拦截的一种现象,其根本原因是浏览器对同源资源的保护
解决方案
1.通过配置@CrossOrigin
要求如下:
1.jdk1.8+
2.spring4.2版本以上
具体代码展示如下
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
/** @deprecated */
@Deprecated
String[] DEFAULT_ORIGINS = new String[]{"*"};
/** @deprecated */
@Deprecated
String[] DEFAULT_ALLOWED_HEADERS = new String[]{"*"};
/** @deprecated */
@Deprecated
boolean DEFAULT_ALLOW_CREDENTIALS = false;
/** @deprecated */
@Deprecated
long DEFAULT_MAX_AGE = 1800L;
/**
* 同origins属性一样
**/
@AliasFor("origins")
String[] value() default {};
/**
* 所有支持域的集合,例如"http://baidu.com"。
* <p>这些值都显示在请求头中的Access-Control-Allow-Origin
* "*"代表所有域的请求都支持
* <p>如果没有定义,所有请求的域都支持
* @see #value
*/
@AliasFor("value")
String[] origins() default {};
/**
* 允许请求头,默认都支持
*/
String[] allowedHeaders() default {};
/**
* 过滤的请求头,默认为空
*/
String[] exposedHeaders() default {};
/**
* 支持的请求方法GET、POST、DELETE
* 默认支持RequestMapping中设置的方法
*/
RequestMethod[] methods() default {};
/**
* 是否允许cookie随请求发送,使用时必须指定具体的域
*/
String allowCredentials() default "";
/**
* 预请求的结果的有效期,默认30分钟
*/
long maxAge() default -1L;
}
通过如何源码分析,可以得出@CrossOrign注解默认支持所有的跨域访问,其可以配置在Controller上,也可以配置到具体的方法上,用法如下
import com.bdcloud.bean.Email;
import com.bdcloud.response.CommonCode;
import com.bdcloud.response.ResponseResult;
import com.bdcloud.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@CrossOrigin
@RestController
@RequestMapping("/email")
public class EmailController {
@Autowired
EmailService emailService;
@GetMapping("/getAll")
@CrossOrigin(maxAge = 300)
public Map getAll(){
System.out.println("wahah");
Map<String,Object> result = new HashMap<>();
List<Email> allEmail = emailService.getAllEmail();
result.put("code",0);
result.put("count",allEmail.size());
result.put("data",allEmail);
return result;
}
}
springframeworker在5.2以后直接使用@CrossOrigin失败,具体解决方案如该篇博客
https://blog.youkuaiyun.com/shuoshuo132
2.1通过配置Filter
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 CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用
corsConfiguration.addAllowedHeader("*"); // 2允许任何头
corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等)
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4
return new CorsFilter(source);
}
}
2.1通过全局配置Filter
//统一过滤器设置
public class DomainFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
chain.doFilter(req, res);
}
@Override
public void destroy() {
}
}
//spring boot过滤器设置
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
DomainFilter domainFilter = new DomainFilter();
registrationBean.setFilter(domainFilter);
List<String> urlPatterns = new ArrayList<String>();
urlPatterns.add("/*");
registrationBean.setUrlPatterns(urlPatterns);
return registrationBean;
}
3.通过Nginx配置转发解决跨域
server {
listen 80;
server_name xxx.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location /client { #访问客户端路径
proxy_pass http://localhost:81;
proxy_redirect default;
}
location /apis { #访问服务器路径
rewrite ^/apis/(.*)$ /$1 break;
proxy_pass http://localhost:82;
}
}