在 Java Web 服务中启用 CORS

Posted

技术标签:

【中文标题】在 Java Web 服务中启用 CORS【英文标题】:Enabling CORS in Java Web Service 【发布时间】:2019-06-11 20:58:24 【问题描述】:

注意:我已经找到了解决方案。我只是发布问题和解决方案,以防其他人遇到类似问题

长话短说:

当我有一个 REACT 客户端应用程序向我在通过 NetBeans 运行的 Payara 服务器上运行的 Java Web 服务器进行 HTTP 发布时,我在浏览器的开发人员工具窗口上收到此 CORS 错误消息:

SEC7120:[CORS] 原点“http://localhost:3000”未找到 Access-Control-Allow-Origin 响应中的“http://localhost:3000” 跨域资源的标头位于 'http://localhost:8080/DatabaseWebService/databaseConnectorMethod'。

有关 CORS 的更多信息,请参阅此网站https://enable-cors.org/

长篇大论:

我有一个在 http://localhost:3000 上运行的 REACT 项目,向我在本地 Payara 服务器版本 4.1.1 上运行的 Java Web 服务 (DatabaseWebService) 发送 HTTP 帖子。 REACT 应用请求的 Web 服务 URL 是“http://localhost:8080/DatabaseWebService/databaseConnectorMethod”

每次我运行 REACT 代码时,都会收到上面列出的 CORS 错误。

这是我发出 http post 请求的 REACT 代码:

            const postData = new URLSearchParams();
            postData.append('var1', 'somedata1');
            postData.append('var2', 'somedata2');
            let axiosConfig = 
                headers: 
                    'Content-Type': 'application/x-www-form-urlencoded'                

            ;

        axios.post('http://localhost:8080/DatabaseWebService/databaseConnectorMethod', postData, axiosConfig)
            .then((res) => 
                console.log("AXIOS POST RESPONSE RECEIVED: ", res);
            )
            .catch((err) => 
                console.log("AXIOS POST ERROR: ", err);
            )

这是我的 servlet 代码:

public class DatabaseConnectorServlet extends HttpServlet 
        @Override
        final protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
                throws ServletException, IOException 

            try 
                System.out.println("DatabaseConnectorServlet Received a HTTP POST");  

                String var1= request.getParameter("var1");
                String var2= request.getParameter("var2");
                System.out.println(var1 + var2);
                response.getWriter().print("I GOT YOUR MESSAGE");
             catch (Exception ex)                           
                response.getWriter().print(ex);
            
        

我在上面的 Java 代码中设置了断点并看到它被命中,我看到它执行了所有命令,包括 response.getWriter().print 没有问题。但是,当我查看浏览器开发人员工具控制台窗口时,我确实看到了 CORS 异常。

【问题讨论】:

【参考方案1】:

解决方案 在 Java Web Service 应用程序中,您需要添加一些标头以允许 Response 对象中的 CORS。这是更新后的 Java 代码,请注意额外的 response.addHeader 代码行:

public class DatabaseConnectorServlet extends HttpServlet 

    @Override
    final protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
            throws ServletException, IOException 

        try 
            System.out.println("DatabaseConnectorServlet Received a HTTP POST");
            response.addHeader("Access-Control-Allow-Origin", "http://localhost:3000"); //Here's the extra line needed to allow CORS to your server side code

            String var1 = request.getParameter("var1");
            String var2 = request.getParameter("var2");
            System.out.println(var1 + var2);
            response.getWriter().print("I GOT YOUR MESSAGE");

         catch (Exception ex) 
                response.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
            response.getWriter().print(ex);
        
    

有了这个更新的代码,我现在可以在运行 React 代码的 Web 浏览器开发工具的控制台窗口上看到示例“我收到你的消息”文本了。

这基本上允许来自不同域/端口(即在本例中为 REACT 应用程序)的 http 请求访问此 java Web 服务的数据。

另外,为了让您知道,您可以包含一些其他额外的标题(我在其他问题上看到),这些标题在我的情况下并不需要,但可能对您的情况有用。以下是附加标题和一些示例值:

 response.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
        response.addHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, X-Auth-Token");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.addHeader("Access-Control-Request-Headers", "Origin, X-Custom-Header, X-Requested-With, Authorization, Content-Type, Accept");
        response.addHeader("Access-Control-Expose-Headers", "Content-Length, X-Kuma-Revision");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");

【讨论】:

在一般情况下,最好在单个位置处理此问题,而不是修改每个请求的标头。此外,在代码中硬编码域也不是一个好主意,因为在生产中它不会localhost:8080 明白。我同意你的两个观点。在其他类似的帖子中,我看到有人指示将服务器配置为接受 CORS,但我不记得实际看到如何这样做的信息。我也确实在其他相关帖子上看到了很多关于在响应标头中添加 Access-Control-Allow-Origin 的答案。我将研究如何在一个地方以某种方式配置它,也许在服务器本身上,并在我弄清楚时考虑更新答案。

以上是关于在 Java Web 服务中启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章

在Java Web Service中启用CORS

在 Visual Studio 开发服务器上为 Soap Web 服务启用 CORS 设置

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

如何使用 Web 服务和 jQuery Ajax 启用 CORS

如何在 jBoss 中启用 CORS

在 Java 服务器端处理 CORS