springboot 前后端分离 跨域问题

一.什么是跨域
跨域是指 不同域名之间相互访问。跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。

也就是如果在A网站中,我们希望使用Ajax来获得B网站中的特定内容
如果A网站与B网站不在同一个域中,那么就出现了跨域访问问题。

二.什么是同一个域
同一协议,同一ip,同一端口,三同中有一不同就产生了跨域。

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。端口不同 本机端口为80

三:前端访问服务器出现的问题:

Access to XMLHttpRequest at 'url' from origin 'null' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response

预运行响应中的访问控制允许头不允许请求头字段内容类型,也就是我们的请求head中包含了不允许的字段内容

包含自定义header字段的跨域请求,浏览器会先向服务器发送OPTIONS请求,探测该服务器是否允许自定义的跨域字段。如果允许,则继续实际的POST/GET正常请求,否则,返回标题所示错误。

解决:在系统过滤器中设置响应头信息:

    @Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		HttpServletResponse response = (HttpServletResponse) servletResponse;
		//跨域请求,*代表允许全部类型
		response.setHeader("Access-Control-Allow-Origin", "*");
		//允许请求方式
		response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
		//用来指定本次预检请求的有效期,单位为秒,在此期间不用发出另一条预检请求
		response.setHeader("Access-Control-Max-Age", "3600");
		//请求包含的字段内容,如有多个可用哪个逗号分隔如下 (如heaer中包含自定义参数,需在此项中指定)
		response.setHeader("Access-Control-Allow-Headers", "content-type,x-requested-with,Authorization, x-ui-request,lang");
		//访问控制允许凭据,true为允许
		response.setHeader("Access-Control-Allow-Credentials", "true");
		// 浏览器是会先发一次options请求,如果请求通过,则继续发送正式的post请求
        // 配置options的请求返回
		if (request.getMethod().equals("OPTIONS")) {
			response.setStatus(HttpStatus.SC_OK);
			response.getWriter().write("OPTIONS returns OK");
			return;
		}
		// 传递业务请求处理
		chain.doFilter(servletRequest, servletResponse);
	}

解决:1.在拦截器中设置OPTIONS请求 设置成 成功!

@Slf4j
public class BlackEndInterceptor implements HandlerInterceptor {

    public static final String CONTENT_TYPE_FILE = "application/json";
    public static final String CONTENT_TYPE_FILE2 = "application/x-www-form-urlencoded";
    private static RedisCacheService redisCacheService = getStringRedisTemplate();

    /**
     * 在请求处理之前进行调用(Controller方法调用之前)
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        log.info("--------------进入过滤器------------------");
        long startTime = System.currentTimeMillis();
        request.setAttribute("InterceptorStartTime", startTime);
        if ("GET".equals(request.getMethod())) {

            if (!validateGet(request, response)) {
                return false;
            }
            return true;
        }
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }
        if (!validatePost(request, response)) {
            return false;
        }
        return true;

    }

2.在过滤器中设置响应头信息:

package com.finance.rst.map.engine.backend.web;

import com.finance.rst.map.engine.backend.service.util.RequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 解决流只能读取一次
 */
@Slf4j
@Component
public class CORSFilter implements Filter {


	public CORSFilter() {
		log.info("CORSFilter init");
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {
		log.info("-----------------doFilter-------------------");
		HttpServletRequest request = new RequestWrapper((HttpServletRequest)req);
		HttpServletResponse response = (HttpServletResponse) res;

		response.setHeader("Access-Control-Allow-Origin", "*");
		response.setHeader("Access-Control-Allow-Credentials", "true");
		response.setHeader("Access-Control-Allow-Headers", "Content-Type");
		response.setHeader("Content-Type", "application/json;charset=utf-8");
		response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
		response.setHeader("Access-Control-Max-Age", "3600");
		/**
		 * Set Cache-Control, Pragma for IE ajax request caching disablement
		 * Custom item X-Session-Token for myself.
		 */
		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig filterConfig) {
	}

	@Override
	public void destroy() {
	}

}

即可!

你可能感兴趣的:(springboot)