简体   繁体   中英

Why delete method doesn't work when post method does?

I am combining two applications, backend (java spring) and frontend (react). I have no communication for the deleteEvenTask request with DELETE http method. The same request when using POST http method, reaches the endpoint. Sending a DELETE query via curl also works. Other requests (getAllEvens with GET method, replaceEvenTask wuth POST method) also work.

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. This explains why it works with POST instead of DELETE and it also explains why it works using curl but not in the browser.

You can configure CORS globally with something along the following lines:

@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:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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