在 Java Servlet 上启用了 CORS,但从前端接收到 CORS 错误

Posted

技术标签:

【中文标题】在 Java Servlet 上启用了 CORS,但从前端接收到 CORS 错误【英文标题】:CORS enabled on Java Servlet yet receiving CORS error from frontend 【发布时间】:2019-11-15 15:13:00 【问题描述】:

我正在编写一个 Web 应用程序,其中客户端将 (JSON) 表单数据发布到服务器,并且服务器也应该使用 JSON 进行响应。服务器端使用 java servlet 编写,在 Tomcat 上运行,客户端使用 Angular 7 编写。不幸的是,即使在通过 HTTP 标头启用 cors 后,我也面临 CORS 错误。我有什么遗漏吗?

这是我在客户端遇到的错误: 从源“http://localhost:4200”访问“http://localhost:8080/mysocial/signIn”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源。

我已阅读以下帖子并尝试了每种解决方案,但问题仍然存在: CORS enabled but still getting CORS error

How to fix CORS issue http request in Angular 5

正如我所说,我已启用 CORS 标头。代码 sn-ps 显示了我的服务器端和客户端代码:

// From my data service (client-side angular 7)
import  Injectable  from '@angular/core';
import  HttpClient, HttpHeaders  from '@angular/common/http';

@Injectable(
  providedIn: 'root'
)
export class DataService 
  private baseUrl: string = "http://localhost:8080/mysocial";
  private http: HttpClient;

  constructor(http: HttpClient)  
    this.http = http;
  

  public authenticateLogin(username: string, password: string) //: boolean
  
    let url: string = `$this.baseUrl/signIn`;
    let header = new HttpHeaders('Accept': 'application/json' ,'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' );
    let httpOptions =  headers: header ;
    let body = username: username, password: password;

    return this.http.post(url, body, httpOptions).subscribe(
      (response) => console.log(response),
      (err) => console.log(err)
    );
    //return true;
  

服务器端代码:

// server-side java servlets code
   private void configResponse(HttpServletResponse response)
   
      response.setContentType("application/json");
      response.addHeader("Access-Control-Allow-Origin", "http://localhost:4200");
      response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
   

   public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
   
      Model model = (Model) getServletContext().getAttribute("model");
      String username = request.getParameter("username");
      String password = request.getParameter("password");

      configResponse(response);
      PrintWriter out = response.getWriter();

      if (model.validateLoginDetails(username, password))
      
         String firstName = model.getUserInfo("firstName", "username", username);
         int id = Integer.parseInt(model.getUserInfo("id", "username", username));

         HttpSession session = request.getSession();
         session.setMaxInactiveInterval(60);
         session.setAttribute("username", username);
         session.setAttribute("firstname", firstName);
         session.setAttribute("id", id);

         JsonObject value = createJsonResponse(username, password, true);
         out.println(value);
      
      else
      
         JsonObject value = createJsonResponse(username, password, false);
         out.println(value);
      
   

我希望服务器将 JSON 发送回客户端,但我收到来自客户端的 CORS 错误。

【问题讨论】:

您的服务器代码似乎只为 POST 响应添加了 Access-Control-Allow-* 响应标头。代码还需要添加 Access-Control-Allow-Origin 和 Access-Control-Allow-Methods 标头以响应 OPTIONS 请求 - 对于 OPTIONS 响应,服务器还需要发回“Access-Control-Allow-Headers” : 内容类型'。处理 CORS 预检 OPTIONS 请求所需的一切。 删除为 POST 响应添加 Access-Control-Allow-Methods 标头的服务器代码部分——该标头仅对 OPTIONS 响应是必需的。在您的前端 javascript 代码中,删除 'Access-Control-Allow-Origin': '*' 部分; Access-Control-Allow-Origin 标头不是请求标头 - 相反,它只是一个响应标头,供服务器发送。 与其尝试在服务器端编写自己的自定义 CORS 处理,不如考虑使用 Tomcat 中已经内置的 CORS 处理。请参阅enable-cors.org/server_tomcat.html 和 tomcat.apache.org/tomcat-9.0-doc/config/filter.html#CORS_Filter 和 ***.com/questions/tagged/cors+tomcat 我已经添加了 tomcat CORS 过滤器,但仍然遇到同样的错误。会不会是代码中的其他内容? 我不知道。我想可能是服务器代码的其他部分在评估过滤器之前捕获并处理了 OPTIONS 请求。如果您查看一些***.com/questions/tagged/cors+tomcat 问题和答案,您可能会发现一个描述类似问题的问题。 【参考方案1】:

为了完整性和任何可能遇到此问题的人,我能够使用此处提供的 tomcat 过滤器解决此问题:http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter(由 sideshowbarker (https://***.com/users/441757/sideshowbarker) 显示)

必须先更改一些服务器配置才能匹配过滤器。我建议根据您的需要自定义过滤器。

【讨论】:

以上是关于在 Java Servlet 上启用了 CORS,但从前端接收到 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring 二级 Servlet 中启用 CORS

在 Java Web 服务中启用 CORS

在Java Web Service中启用CORS

如何在 JBoss AS 上使用 java RESTful Web 服务启用 CORS

在 Java Play 应用中启用 CORS 过滤器

如何将 ActiveMQ AJAX servlet 与 CORS 一起使用?