Maison  >  Article  >  développement back-end  >  L'utilisation de POST pour ajouter au même point de terminaison GET et différentes requêtes aboutissent à des messages d'erreur incohérents

L'utilisation de POST pour ajouter au même point de terminaison GET et différentes requêtes aboutissent à des messages d'erreur incohérents

WBOY
WBOYavant
2024-02-11 20:50:11813parcourir

使用 POST 添加到 GET 相同的端点和不同的查询最终会出现不一致的错误消息

l'éditeur php Banana est là pour répondre à une question commune à tout le monde : en utilisant POST pour ajouter à GET le même point de terminaison et des requêtes différentes, vous risquez de vous retrouver avec des messages d'erreur incohérents. Dans le développement Web, GET et POST sont des méthodes de requête HTTP couramment utilisées pour transmettre des données au serveur. La méthode GET ajoute les données à l'URL, tandis que la méthode POST encapsule les données dans le corps de la requête. Lorsque nous ajoutons une requête POST au même point de terminaison d'une requête GET, des messages d'erreur incohérents peuvent survenir si les paramètres de requête sont différents. En effet, le serveur traite la demande en fonction de la méthode de demande et des paramètres de requête. Différents paramètres de requête peuvent amener le serveur à renvoyer des résultats différents. Par conséquent, lors de l'utilisation des requêtes POST et GET, nous devons prêter attention à la cohérence des points de terminaison et des paramètres de requête pour éviter les messages d'erreur inattendus.

Contenu de la question

Lors de l'ajout du même itinéraire en utilisant différentes méthodes, la réponse de chaque méthode query get call est différente, mais comme l'autre méthode est post, elle ne devrait pas être affectée.

Par courrier : Aire de jeux : https://go.dev/play/p/xzoakpehggy

// you can edit this code!
// click here and start typing.
package main

import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"time"

    "github.com/gorilla/mux"

)

func main() {

    r := mux.newrouter()
    
    r.handlefunc("/api/v2", func(w http.responsewriter, r *http.request) {
        // an example api handler
        fmt.fprintf(w, "you made a post request")
        json.newencoder(w).encode(map[string]bool{"ok": true})
    }).methods("post")
    
    r.handlefunc("/api/v2", func(w http.responsewriter, r *http.request) {
        // an example api handler
        fmt.fprintf(w, "you made a get request")
        json.newencoder(w).encode(map[string]bool{"ok": true})
    }).
        queries("from", "{from:[0-9]+}",
            "to", "{to:[0-9]+}").methods("get")
    
    
    srv := &http.server{
        handler: r,
        addr:    "127.0.0.1:8000",
        // good practice: enforce timeouts for servers you create!
        writetimeout: 15 * time.second,
        readtimeout:  15 * time.second,
    }
    go srv.listenandserve()
    
    
    req2 := httptest.newrequest("get", "/api/v2?from=3&to=-5", nil)
    out2 := httptest.newrecorder()
    
    r.servehttp(out2, req2)
    
    fmt.println(out2.code)
    fmt.println(out2)

}

404 attendu, 405 réel

Lors de la suppression d'un message Aire de jeux : https://go.dev/play/p/exif00_wrfw

// You can edit this code!
// Click here and start typing.
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "net/http/httptest"
    "time"

    "github.com/gorilla/mux"
)

func main() {

    r := mux.NewRouter()

    r.HandleFunc("/api/v2", func(w http.ResponseWriter, r *http.Request) {
        // an example API handler
        fmt.Fprintf(w, "You made a GET request")
        json.NewEncoder(w).Encode(map[string]bool{"ok": true})
    }).
        Queries("from", "{from:[0-9]+}",
            "to", "{to:[0-9]+}").Methods("GET")


    srv := &http.Server{
        Handler: r,
        Addr:    "127.0.0.1:8000",
        // Good practice: enforce timeouts for servers you create!
        WriteTimeout: 15 * time.Second,
        ReadTimeout:  15 * time.Second,
    }
    go srv.ListenAndServe()


    req2 := httptest.NewRequest("GET", "/api/v2?from=3&to=-5", nil)
    out2 := httptest.NewRecorder()

    r.ServeHTTP(out2, req2)

    fmt.Println(out2.Code)

}

Le résultat est 404

Pour les demandes get, le routage et les résultats doivent être cohérents. 404-s

Je suis curieux de savoir si quelqu'un a déjà rencontré ce problème ?

Solution de contournement

Le routeur tentera de trouver une correspondance en fonction du chemin et des paramètres de requête. La route d'obtention ne correspondait pas car les paramètres de la chaîne de requête ne répondaient pas aux exigences.

Mais ce chemin correspond à la route post car cette route ne se soucie pas de ces paramètres de requête. Ensuite, en vérifiant la méthode de requête, elle ne correspond pas à la route, donc 405 method not allowed est renvoyé (la route a un gestionnaire, mais la méthode est différente).

Vous pouvez obtenir le comportement souhaité en ajoutant un gestionnaire get fourre-tout pour le même chemin :

// You can edit this code!
// Click here and start typing.
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "net/http/httptest"
    "time"

    "github.com/gorilla/mux"
)

func main() {

    r := mux.NewRouter()

    r.HandleFunc("/api/v2", func(w http.ResponseWriter, r *http.Request) {
        // an example API handler
        fmt.Fprintf(w, "You made a POST request")
        json.NewEncoder(w).Encode(map[string]bool{"ok": true})
    }).Methods("POST")

    r.HandleFunc("/api/v2", func(w http.ResponseWriter, r *http.Request) {
        // an example API handler
        fmt.Fprintf(w, "You made a GET request")
        json.NewEncoder(w).Encode(map[string]bool{"ok": true})
    }).
        Queries("from", "{from:[0-9]+}",
            "to", "{to:[0-9]+}").
        Methods("GET")
    r.HandleFunc("/api/v2", func(w http.ResponseWriter, r *http.Request) {
        http.Error(w, "", http.StatusNotFound)
    }).Methods("GET")

    srv := &http.Server{
        Handler: r,
        Addr:    "127.0.0.1:8000",
        // Good practice: enforce timeouts for servers you create!
        WriteTimeout: 15 * time.Second,
        ReadTimeout:  15 * time.Second,
    }
    go srv.ListenAndServe()

    req2 := httptest.NewRequest("GET", "/api/v2?from=3&to=-5", nil)
    out2 := httptest.NewRecorder()

    r.ServeHTTP(out2, req2)

    fmt.Println(out2.Code)

}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer