在某个时刻,我正在为我的第一个“真正的”WebServer 项目而苦苦挣扎。到目前为止,我一直使用 Nodejs 服务器。但由于我想使用我自己的 MySQL 数据库,所以这次我决定使用普通的 JAVA 后端。
后端在由互联网提供商托管的虚拟 Ubuntu 服务器上的 Glassfish 7.0.12 上运行 JAVA EE (JAVA 17) 项目。后端隐藏在用作 https 代理的 NGINX 服务器后面。我对所有服务器都执行此操作,这是现在在同一台 Linux 服务器上运行的第四个服务器。
前端是用 Angular 16.x 构建的,目前仅提供一个登陆页面和 2 个按钮,这些按钮应该简单地调用 2 个后端服务,就像我在浏览器的地址字段或使用 Postman 那样。
我成功地将应用程序部署在 glassfish 服务器上,我可以通过 https 调用登陆页面。目前为止没有任何问题。
通过 Postman 或仅浏览器的地址字段调用 2 个已实现的后端服务时,我可以轻松调用它们。一切都按预期进行。
但是一旦我点击其中一个按钮,用户界面就会闪烁一眨眼,然后重新加载整个登陆页面。查看浏览器控制台后发现,出现了 NS_BINDING_ABORTED 错误。
所以我使用控制台进行了更多调查,发现与我的其他项目不同,http标头中的“Referer”字段看起来像这样
https://my-domain/my-context-root/?
最后这个问号是哪里来的?我想这可能是解决问题的关键。因为我的其他登陆页面都没有提出这个附录。
如果我对 CORS 的理解正确,那么这个引用者用于应用同源规则。由于存在一个不必要的字符,因此比较失败。
有人知道这个问号从何而来以及如何删除它?
这是出现错误后我的浏览器控制台
这就是我的index.html 的样子
这里是CORS相关的后端代码。我只是在尝试解决问题时添加了这个过滤器,但它根本没有帮助,因为看起来调用甚至没有离开我的浏览器。
package org.my-app_server.base;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.container.ContainerResponseFilter;
import jakarta.ws.rs.ext.Provider;
@Provider
public class CorsResourceFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
responseContext.getHeaders().putSingle("Access-Control-Allow-Origin", "*");
responseContext.getHeaders().putSingle("Access-Control-Allow-Credentials", "true");
responseContext.getHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
responseContext.getHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept");
}
}
这是我在服务器启动时调用它的地方
package org.my-app_server.base;
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;
@ApplicationPath("/api")
public class RRSSApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> resources = new HashSet<>();
resources.add(CorsResourceFilter.class);
return resources;
}
}
我找到了解决方案。它与 Glassfish 完全无关。
我的按钮在里面
<form> </form>
标签。
Angular 尝试在按下其中一个按钮后直接传输表单。这会导致整个应用程序立即重新加载,因此请求在正确处理之前就被丢弃了......