No ‘Access-Control-Allow-Origin’ header is present on the requested resource
前后端分离就会出现跨域问题。
发生跨域问题的原因:
1,浏览器限制
2,跨域:发出去的请求与监听的服务器,协议,域名,端口任何一个不一样都会产生跨域问题。
3,发出的是xmlHttpRequest请求
同时满足,才有可能产生跨域安全问题。
解决办法
1,注册过滤器,添加响应头来告诉浏览器允许跨域
对简单请求的跨域
package com.ajax.ajaxdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@SpringBootApplication
public class AjaxDemoApplication {
public static void main(String[] args) {
SpringApplication.run(AjaxDemoApplication.class, args);
}
@Bean
public FilterRegistrationBean registerFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
//拦截所有请求
bean.addUrlPatterns("/*");
bean.setFilter(new Filter() {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) servletResponse;
//表示允许来自"http://localhost:8081"的请求
res.addHeader("Access-Control-Allow-Origin", "http://localhost:8081");
//表示允许跨域的请求的方法
res.addHeader("Access-Control-Allow-Methods", "Get");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
});
return bean;
}
}
对复杂请求的跨域
往之前的fiter里添加上这一句,表示可以允许复杂请求跨域
res.addHeader("Access-Control-Allow-Headers","Content-Type");
带cookie的跨域请求
在之前origin里,允许跨域请求的来源可以用通配符*表示,允许所有域进行跨域请求,但是如果是带cookie的跨域请求,则只能明确表示域来源,不能使用通配符
res.addHeader("Access-Control-Allow-Origin", "http://localhost:8081");
并且还需要加上一句
res.addHeader("Access-Control-Allow-Credentials","true");
带cookie的时候如何允许所有域
浏览器发现请求是跨域的时候,会在请求头里面增加Origin字段,只要filter得到这个字段,再把它作为允许的来源就可以了。(文字表达欠佳)
看doFilter方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) servletResponse;
HttpServletRequest req = (HttpServletRequest) servletRequest;
String origin = req.getHeader("Origin");
if (!origin.isEmpty()){
//表示允许来自"http://localhost:8081"的请求
res.addHeader("Access-Control-Allow-Origin", origin);
}
//表示允许跨域的请求的方法
res.addHeader("Access-Control-Allow-Methods", "Get");
res.addHeader("Access-Control-Allow-Headers","Content-Type");
filterChain.doFilter(servletRequest, servletResponse);
}
2,spring解决跨域问题
直接在类或则方法上面添加@CrossOrigin注解就可以了。