多方式解决跨域问题

为什么会有跨域问题

浏览器拒绝执行其它域名下的 ajax 运作:

我想自己做一个搜索网站,但我不会搜索技术,怎么办呢?如果能发起 ajax 请求到百度就好了呢,可以这样吗?

肯定不行,如果浏览器在自己的服务器域名对应的 html 页面内,发起 ajax 请求偷盗 www.baidu.com 域名下的内容来填充自己的页面,整个互联网秩序将混乱。

为了防止这种混乱,W3C 组织制定了浏览器安全规范,即 html 页面发起的 ajax 请求仅限于同域名后端范围,跨越域名的ajax请求不得执行,此谓跨域问题

从程序员的角度来看,当发生跨域时,浏览器的控制台会给出没有 “Access-Control-Allow-Origin” 的报错。

解决方法

方案一:Nginx 配置

Nginx 解决跨域问题

方案二:Filter 配置

利用 servlet 规范

public class CorsFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }


    /*
    * value、origins属性:配置允许访问的源,如: http://anxminise.cc,*表示允许全部的域名
        methods属性:配置跨域请求支持的方式,如:GET、POST,且一次性返回全部支持的方式
        maxAge属性:配置预检请求的有效时间, 单位是秒,表示:在多长时间内,不需要发出第二次预检请求
        allowCredentials属性:配置是否允许发送Cookie,用于 凭证请求, 默认不发送cookie
        allowedHeaders属性:配置允许的自定义请求头,用于 预检请求
        exposedHeaders属性:配置响应的头信息, 在其中可以设置其他的头信息,不进行配置时, 默认可以获取到Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma字段
    *
    * */
    @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.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        chain.doFilter(req, res);
    }

    @Override
    public void destroy() {

    }
}
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    //父容器
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{SpringContainer.class};
    }

    //SpringMVC配置子容器
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{MvcContainer.class};
    }

    //获取DispatcherServlet的映射信息
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    @Override
    protected Filter[] getServletFilters() {
        CorsFilter corsFilter = new CorsFilter();
        return new Filter[]{corsFilter};
    }
}

为什么这么写有用,见 Spring5 源码阅读笔记(5)基于注解的方法替换 web.xml

方案三:@EnableWebMvc 配置

原理上,用的 Spring 里的 Interceptor

@Configuration
@EnableWebMvc
public class AppConfig implements WebMvcConfigurer {
 
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/user/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT","PATCH")
                .maxAge(3600);
    }
}

方案四:@CrossOrigin 配置

在方法上添加注解,也可以

@CrossOrigin(origins = "*"
            ,allowedHeaders = "x-requested-with"
            ,allowCredentials = "true"
            ,maxAge = 3600
            ,methods = {RequestMethod.GET,RequestMethod.POST,RequestMethod.OPTIONS,RequestMethod.DELETE})
发布了185 篇原创文章 · 获赞 271 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44367006/article/details/105019210