无法发送 POST 和 body

Can not send POST with body

我的申请有问题。我有各种工作正常的 REST enpoints。但现在我想用 body 发送 POST 请求。我已经有 2 个用于 POST 方法的端点,但数据是使用 PathParam 发送的。

我创建了新的端点,但是当我发送请求时我收到了 CORS 错误。当我在请求中使用没有 body 的相同端点时,一切都很好,但当然在后端,我没有从前端获取任何数据(我在方法中有断点)。

这是我从 angular 应用程序发送请求的方式:

post(requestUrl: string, body?: any): Observable<any> {
  return this.httpClient.post<any>(this.API_URL + requestUrl, {password: 'test'});
}

发送请求后我得到:

从来源 'http://localhost:4200' 访问 'http://localhost:8080/...' 处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否 'Access-Control-Allow-Origin' header 出现在请求的资源上。

如果我像这样发送请求(没有 body),这个端点工作正常:

post(requestUrl: string, body?: any): Observable<any> {
  return this.httpClient.post<any>(this.API_URL + requestUrl);
}

在后端,我添加了 CORS 设置:

return Response.ok(object).header("Access-Control-Allow-Origin", "*")
      .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
      .allow("OPTIONS").build();

当我从 Insomnia 发送请求时一切正常 - 我可以发送 body 并且我在后端收到发送的数据。

我应该以某种方式在前端设置请求 headers 吗?

这是我的 AdminApiController class:

@Path("/admin")
@RequestScoped
public class AdminApiController extends BaseApiController {

@Inject
private AdminAssembler adminAssembler;

@POST
@Path("/login")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response login(LoginRequest request) {
  return Response.ok(adminAssembler.login(request))
      .header("Access-Control-Allow-Origin", "*")
      .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
      .header("Access-Control-Allow-Headers", "Content-Type")
      .allow("OPTIONS").build();
  }
}

当您的 angular 应用程序在 POST 请求中发送 JSON 负载时,它可能会添加 header Content-Type: application/json。此 header 将 POST 请求归类为“non-simple”请求(即,如果不附加 HTML <form> 元素,则无法产生请求 Java脚本)。这样的“non-simple”请求会导致浏览器发出预检请求,即带有 headers

的 OPTIONS 请求
Origin: http://localhost:4200
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type

服务器必须用 Access-Control-Allow-Origin header 和 Access-Control-Allow-Headers: Content-Type 响应。如果没有,浏览器将不会发出 POST 请求并显示您观察到的错误。

您的 Java 代码仅涵盖 @POST,不涵盖 @OPTIONS,这就是服务器 响应预检请求的原因必要 headers。如何最好地处理服务器上 所有 端点的 OPTIONS 请求是 Java 专家(我不是)的问题。

您需要定义您的 httpOptions。 试试这个。

httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json'
    })
};

post(requestUrl: string, body?: any): Observable<any> {
  this.httpClient.post<any>(this.API_URL + requestUrl, {password: 'test'}, this.httpOptions)
}

让我知道它是否适合你。