返回

Vue 与 Java Servlet 跨域问题:如何解决 CORS 预检请求错误?

vue.js

Vue 与 Java Servlet 协同开发:解决跨域资源共享 (CORS) 预检请求问题

前后端分离架构已成为现代 Web 开发的主流模式,Vue.js 以其轻量、高效和组件化的特点,常被用作前端框架;而 Java Servlet 作为 Java Web 开发的基础技术,则常被用于构建后端服务。两者结合,可以高效地搭建功能完备的 Web 应用。

但在实际开发中,由于浏览器同源策略的限制,Vue 前端与 Java Servlet 后端进行数据交互时,常会遇到跨域资源共享 (CORS) 的问题。特别是发送 POST 请求时,浏览器会先发送一个 OPTIONS 预检请求,若服务器配置不当,则会导致请求失败。本文将深入剖析 CORS 预检请求错误的根源,并提供一套基于 Java Servlet 的解决方案,帮助你轻松解决 Vue 与 Java Servlet 协同开发中的跨域难题。

浏览器安全策略与 CORS 机制:理解跨域问题的根源

为保障用户数据安全,现代浏览器默认实施同源策略。该策略限制了不同源的脚本对当前文档的访问权限,只有当网页的协议、域名和端口号与请求目标地址完全一致时,才被视为同源,允许访问。

跨域资源共享 (CORS) 则提供了一种机制,允许服务器通过在 HTTP 响应中添加特定的头部信息,明确告知浏览器允许哪些跨域请求访问其资源。

当浏览器发起跨域请求时,并非直接发送目标请求,而是先发送一个 OPTIONS 预检请求到服务器。预检请求就像一次“试探”,浏览器通过它向服务器确认是否允许该跨域请求。服务器收到预检请求后,需检查请求头信息,并通过设置相应的 CORS 头部信息来表明允许的源、请求方法、请求头等信息。

Java Servlet 中配置 CORS 过滤器:构建跨域访问的桥梁

针对 Vue 与 Java Servlet 跨域问题,我们可以在 Java Servlet 后端配置 CORS 过滤器,拦截请求并添加相应的响应头,从而允许 Vue 前端进行跨域访问。具体步骤如下:

1. 创建 CORS 过滤器

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

public class CORSFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        httpResponse.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
        httpResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        httpResponse.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        httpResponse.addHeader("Access-Control-Max-Age", "3600");

        if (httpRequest.getMethod().equals("OPTIONS")) {
            httpResponse.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {}
}

这段代码创建了一个名为 CORSFilter 的过滤器,它实现了 Filter 接口。

2. 在 web.xml 文件中注册过滤器

<filter>
    <filter-name>CORSFilter</filter-name>
    <filter-class>com.example.CORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>CORSFilter</filter-name>
    <url-pattern>/*</url-pattern> 
</filter-mapping>

这段代码将 CORSFilter 注册到 Servlet 容器中,并将其映射到所有请求路径,即 /*

代码说明

  • Access-Control-Allow-Origin: 指定允许访问资源的源地址,这里设置为 Vue 前端域名 http://localhost:8080,你需要根据实际情况修改。
  • Access-Control-Allow-Methods: 指定允许的 HTTP 请求方法,例如 GET、POST、PUT、DELETE 等。
  • Access-Control-Allow-Headers: 指定允许的自定义请求头,例如 Content-TypeAuthorization 等。
  • Access-Control-Max-Age: 指定预检请求的缓存时间 (单位: 秒),浏览器在缓存时间内无需再次发送预检请求。

验证解决方案:确保跨域请求畅通无阻

完成上述配置后,重启 Java Servlet 服务器,并从 Vue 前端再次发送 POST 请求。在浏览器开发者工具的网络请求列表中,检查请求响应头,确认服务器已经添加了相应的 CORS 头部信息。

如果一切配置正确,浏览器将允许跨域请求,你的 Vue 前端代码就能成功与 Java Servlet 后端进行数据交互了。

常见问题解答:扫清跨域配置的障碍

  1. 为什么配置了 CORS 过滤器,浏览器依然提示跨域错误?

    • 首先,确保你的 Java Servlet 服务器已经正确加载并启用了 CORS 过滤器。
    • 其次,检查 Access-Control-Allow-Origin 的值是否与 Vue 前端域名完全一致,包括协议、域名和端口号。
    • 最后,一些浏览器插件可能会拦截跨域请求,尝试禁用相关插件或使用其他浏览器进行测试。
  2. Access-Control-Allow-Origin 可以设置为 * 吗?

    • 可以,但这样做会允许所有网站访问你的资源,存在安全风险,建议仅允许可信的域名访问。
  3. 如何允许携带 Cookie 进行跨域请求?

    • 需要在服务器端设置 Access-Control-Allow-Credentials 头部信息为 true,同时在前端发送请求时,设置 withCredentials 属性为 true
  4. 预检请求会对性能造成影响吗?

    • 会,因为浏览器需要等待预检请求的响应才能发送实际请求,可以通过设置 Access-Control-Max-Age 头部信息来缓存预检请求结果,减少预检请求次数。
  5. 除了使用过滤器,还有哪些方法可以配置 CORS?

    • 可以使用 Java Servlet 3.0 提供的 @CrossOrigin 注解,直接在 Servlet 类或方法上进行配置。

总结:畅享前后端分离开发的便捷

通过本文的讲解,我们深入理解了 CORS 预检请求错误的原因,并掌握了在 Java Servlet 中配置 CORS 过滤器的具体方法。合理地配置 CORS 策略,能够有效地解决 Vue 与 Java Servlet 跨域问题,保障前后端数据交互的顺利进行,让你更加专注于业务逻辑的实现,享受前后端分离开发带来的便捷。