使用 Javascript 从 HTML 页面调用时,Golang REST API PUT 和 DELETE 请求不起作用

Golang REST API PUT and DELETE request doest work when calling from HTML page using Javascript

我正在尝试在 Go 中编写 REST API,当我通过 postman 运行 时所有方法都工作正常,但是当从 [=33= 调用 PUT 和 Delete 方法时] 使用 JAVA 脚本函数的页面无法正常工作。是否有相同的替代方案?

这是我在 main.go 文件中的 Go 处理程序。

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", HomePageHandler).Methods("GET")
    router.HandleFunc("/demo", CreateDemoDetail).Methods("POST") // Add New row
    router.HandleFunc("/demo", GetAllDemoDetails).Methods("GET") // Fetch all details
    router.HandleFunc("/demo/{id}", GetDemoDetail).Methods("GET") // Fetch Single row
    router.HandleFunc("/demo", UpdateDemoDetails).Methods("PUT") // Update Single row
    router.HandleFunc("/demo", DeleteDemo).Methods("DELETE")     // Delete Single row
    log.Fatal(http.ListenAndServe(":8080", router))
}

以下是调用处理程序的Java脚本函数,

 function submitForm(reqtype){
          var form = document.getElementById("demoform");      
    
          if (reqtype == "Delete"){
            form.action = 'http://localhost:8080/demo';
           form.method='PUT';      
          }
          if (reqtype == "Update"){
            form.action = 'http://localhost:8080/demo';
            form.method='DELETE';      
    
          }      
    
          form.submit();
        }
      </script>

如果我将处理程序更改为 router.HandleFunc("/updatedemo", UpdateDemoDetails).Methods("POST") 而不仅仅是 /demo 和 POST 的方法java 脚本,但当它的 demo/ 和方法是 PUT/Delete.

时不是

有趣的是,当端点为 demo/ 或 get demo 且方法为 POST/GET/PUT/Delete 时,它与 Postman 完美配合。但不是来自 HTML 形式的 Java 脚本调用。

我应该采取什么最佳方法?

method attribute 仅支持 GET 和 POST HTTP 动词。

要使用 PUT 或 DELETE,您需要使用 fetch or XMLHttpRequest 进行请求。

如果您的 Web 服务器是 运行 与您的 API 不同的主机/端口,我会查看 CORS (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)。

按照评论中的建议,检查您的浏览器 JS 日志/控制台。如果 CORS 是你的问题,应该有明确的错误消息。

经过一番研究,我找到了解决问题的方法。现在我可以将 URL 保留为“demo/”来处理所有操作 (POST/GET/PUT/DELETE)。

我在 main.go 页面中创建了一个 HTTP 方法覆盖函数,还有一个隐藏的文本字段提供了 HTML 页面中的实际方法名称。使用此文件,来自 JAva 脚本的 Post/Get 请求在服务器端被转换为 PUT/DELETE。

main.go

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", HomePageHandler)

    router.HandleFunc("/demo", formHandler)        // Handle all POST/GET/PUT/DELETE requests
    err := http.ListenAndServe(":8080", router)
}



func formHandler(w http.ResponseWriter, r *http.Request) {

    method := r.FormValue("_method")        
    fmt.Println(method)

    if method == "PUT" || method == "DELETE" {
        r.Method = method

    }

    switch r.Method {
    case "GET":
        t, err := template.New("form").Parse("form")
        if err != nil {
            http.Error(w, err.Error(), 500)
        }
        // View All Demo
        GetAllDemoDetails(w, r)
        fmt.Println(t)
    case "POST":
        // Add New Demo
        CreateDemoDetail(w, r)
    case "PUT":
        // Update Demo
        UpdateDemoDetails(w, r)
    case "DELETE":
        // Delete Demo
        DeleteDemo(w, r)
    default:
        HomePageHandler(w, r)
    }
}

已从 HTML 页修改 JAVAScript。

<script>
    function submitForm(reqtype){
      var form = document.getElementById("demoform");      

      if (reqtype == "Delete"){
        form._method.value="DELETE"        
        form.action = 'http://localhost:8080/demo';

      }
      if (reqtype == "Update"){
        form._method.value="PUT"
        form.action = 'http://localhost:8080/demo';
      }            
      form.method='POST';              
      form.submit();
    }
  </script>

以及最重要的隐藏字段,它将 Delete/PUT 方法传递给请求中的服务器。

<input type="hidden" name="_method">
<button type="button" onclick="submitForm('Update');">Update</button>

虽然此解决方案有效,但我想知道这是否是我可以采用的最佳方法? 请求Golang堆栈社区分享您宝贵的想法。