如何处理从 servlet 中的 Angular 应用程序发送的预检请求?
Posted
技术标签:
【中文标题】如何处理从 servlet 中的 Angular 应用程序发送的预检请求?【英文标题】:How to handle the preflight request send from an angular application in your servlet? 【发布时间】:2020-09-07 23:03:36 【问题描述】:我正在 Angular 中创建一个项目,该项目从 localhost:8080 上运行的 tomcat 应用程序获取用户的 json。现在我正在尝试使用 http.put 更新用户。当我发送我的 put 请求时,我在控制台中打印了这个错误:
从源“http://localhost:4200”访问“http://localhost:8080/Servlet?command=UpdateUser”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源上。
我的 servlet 使用了一个 handlerfactory,它使正确的处理程序来处理请求。 UpdateUser 处理程序现在有这个代码:
public class UpdateUser extends RequestHandler
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
Enumeration<String> params = request.getParameterNames();
System.out.println(params);
while (params.hasMoreElements())
String paramName = params.nextElement();
System.out.println(paramName + ":" + request.getParameter(paramName));
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "X-PINGOTHER,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
response.setStatus(HttpServletResponse.SC_ACCEPTED);
注意:我只是将 while 循环放在那里,这样我就可以看到我的 Angular 应用程序中的内容是如何到达我的处理程序的。
在我的 Angular 应用程序的 app.component.ts 中,我有这段代码来更新用户:
updateUser(user): void
this.userService.updateUser(user).subscribe();
这会在我的 user.service.ts 中调用这个方法:
private httpOptions = headers: new HttpHeaders(
'Content-Type': 'application/json'
);
updateUser(user): Observable<User>
return this.http.put<User>(this.updateUsersUrl, user, this.httpOptions);
在控制台的网络选项卡中,我看到我的处理程序被调用,但没有打印任何内容。 所以我想我可能需要在其他地方处理我的预检请求?
【问题讨论】:
这是一个 CORS 问题。浏览器在执行实际请求之前执行 OPTIONS 请求。确保您的 APi 响应 OPTIONS 请求的有效 CORS 标头。 我不是已经通过在我的处理程序中设置所有这些标头来做到这一点吗?还是我误会了? 我可以看到它的样子,但它似乎不起作用:-)。尝试使用 Postman 或其他工具在localhost:8080/Servlet?command=UpdateUser 触发 OPTIONS 请求,并查看 CORS 标头是否存在.. 哦,我完全忘记了尝试使用邮递员,谢谢!我收到的标题是:“ALLOW GET,HEAD,POST,OPTIONS”、“CONTENT-LENGTH 0”和一个日期。我在代码中设置的其他标题似乎没有出现... 我只是尝试发送一个 HEAD 请求,然后我得到了所有的标头 【参考方案1】:在我的 servlet 中覆盖 doOptions 方法并在那里设置所有标题,似乎可以解决问题
【讨论】:
以上是关于如何处理从 servlet 中的 Angular 应用程序发送的预检请求?的主要内容,如果未能解决你的问题,请参考以下文章
如何处理从 Gdiplus::DrawArc 返回的零星 OutOfMemory 错误代码?