简体   繁体   English

为什么 post 方法有效时 delete 方法无效?

[英]Why delete method doesn't work when post method does?

I am combining two applications, backend (java spring) and frontend (react).我正在结合两个应用程序,后端(java spring)和前端(react)。 I have no communication for the deleteEvenTask request with DELETE http method.对于使用 DELETE http 方法的 deleteEvenTask 请求,我没有任何通信。 The same request when using POST http method, reaches the endpoint.使用 POST http 方法时,相同的请求到达端点。 Sending a DELETE query via curl also works.通过 curl 发送 DELETE 查询也可以。 Other requests (getAllEvens with GET method, replaceEvenTask wuth POST method) also work.其他请求(使用 GET 方法的 getAllEvens,使用 POST 方法的 replaceEvenTask)也可以工作。

const url = "http://localhost:8011/api/evens";
const EvenAPI = {
  getAllEvens: async function () {
    const options = {
      method: 'GET'
    }
    const response = await window.fetch(url, options);
    return response.json();
  },
  replaceEvenTask: async function (evenTask) {
    const options = {
      method: 'POST',
      body: (JSON.stringify(evenTask)),
    }
    return window.fetch(url, options);
  },
  deleteEvenTask: async function (id) {
    const options = {
      method: 'DELETE'
    }
    return window.fetch(url + '/' + id, options);
  }
}

export default EvenAPI;
package pl.artapps.rest;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pl.artapps.entity.Issue;
import pl.artapps.service.IssueService;

import java.util.List;

@RestController
@RequestMapping("/api/evens")
public class EvenController {

    private static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
    private final IssueService issueService;

    public EvenController(IssueService issueService) {
        this.issueService = issueService;
    }

    @GetMapping
    public ResponseEntity<List<Issue>> getEven() {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        return ResponseEntity.ok()
                .headers(responseHeaders)
                .body(issueService.findEvens());
    }

    @PostMapping
    public ResponseEntity<String> updateEven(@RequestBody String issue) {
        boolean updated = issueService.updateEven(issue);
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        if (updated) {
            return ResponseEntity.ok()
                    .headers(responseHeaders)
                    .body("updated");
        } else {
            return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE)
                    .headers(responseHeaders)
                    .body("406");
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<String> deleteEven(@PathVariable Long id) {
        boolean deleted = issueService.deleteEven(id);
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        if (deleted) {
            return ResponseEntity.ok()
                    .headers(responseHeaders)
                    .body("deleted");
        } else {
            return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE)
                    .headers(responseHeaders)
                    .body("406");
        }
    }
}

Errors错误

XHR OPTIONS http://localhost:8011/api/evens/219 CORS Missing Allow Origin

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8011/api/evens/219. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 403.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8011/api/evens/219. (Reason: CORS request did not succeed). Status code: (null).

XHR DELETE http://localhost:8011/api/evens/219

Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.

These two simple diffs make it working fine:这两个简单的差异使它工作正常:

Index: src/api/EvenAPI.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/api/EvenAPI.js b/src/api/EvenAPI.js
--- a/src/api/EvenAPI.js    (revision ff2dc11b6485d5d55da7b59473f177dd77691b22)
+++ b/src/api/EvenAPI.js    (date 1639381203588)
@@ -16,7 +16,7 @@
   },
   deleteEvenTask: async function (id) {
     const options = {
-      method: 'DELETE'
+      method: 'POST'
     }
     return window.fetch(url + '/' + id, options);
   }
Index: src/main/java/pl/artapps/rest/EvenController.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/pl/artapps/rest/EvenController.java b/src/main/java/pl/artapps/rest/EvenController.java
--- a/src/main/java/pl/artapps/rest/EvenController.java (revision ec8c30f5a6aa9283f444fa418103dc3c2f35a584)
+++ b/src/main/java/pl/artapps/rest/EvenController.java (date 1639381151968)
@@ -51,7 +51,7 @@
         }
     }
 
-    @DeleteMapping("/{id}")
+    @PostMapping("/{id}")
     public ResponseEntity<String> deleteEven(@PathVariable Long id) {
         boolean deleted = issueService.deleteEven(id);
         HttpHeaders responseHeaders = new HttpHeaders();

By default, CORS Spring configuration allows all origins and GET, HEAD and POST methods.默认情况下,CORS Spring 配置允许所有来源和 GET、HEAD 和 POST 方法。 This explains why it works with POST instead of DELETE and it also explains why it works using curl but not in the browser.这解释了为什么它可以使用 POST 而不是 DELETE,它还解释了为什么它可以使用 curl 而不是在浏览器中工作。

You can configure CORS globally with something along the following lines:您可以使用以下行全局配置 CORS :

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/whatever-context-path/**")
            .allowedOrigins("*") // You would want to configure only the domain of your FE application
            .allowedMethods("GET", "HEAD", "POST", "DELETE");
    }
} 

You can read more about this in the following online resources:您可以在以下在线资源中阅读更多相关信息:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM