J'utilise le framework Web golang et gin-gonic/gin sur le backend et je réagis axios sur le frontend. J'essaie de le résoudre depuis deux jours et j'obtiens toujours la même erreur ci-dessous :
cors policy: response to preflight request doesn't pass access control check: no 'access-control-allow-origin' header is present on the requested resource.
Cette erreur ne se produit que lorsque j'essaie d'envoyer une demande de correctif, cette demande nécessite donc une demande d'options de contrôle en amont, mais tout avec get et post fonctionne comme prévu, ils n'exécutent aucune vérification de contrôle en amont.
Voici le code de configuration de mon routeur :
package main import ( "book_renting/api" "log" "net/http" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/contrib/cors" "github.com/gin-gonic/gin" _ "github.com/lib/pq" ) func main() { router := gin.default() store := cookie.newstore([]byte("your-secret-key")) store.options(sessions.options{maxage: 60 * 60 * 24}) router.use(cors.default()) router.use(sessions.sessions("sessions", store)) router.use(func(c *gin.context) { host := c.request.header.get("origin") c.writer.header().set("access-control-allow-origin", host) c.writer.header().set("access-control-allow-credentials", "true") c.writer.header().set("access-control-allow-headers", "content-type, authorization") c.writer.header().set("access-control-allow-methods", "get, post, put, delete, patch, options") if c.request.method == "options" { log.println("handling options request") c.abortwithstatus(http.statusnocontent) return } log.println("executing cors middleware") c.next() }) router.post("/login", api.handlelogin) router.get("/logout", api.handlelogout) router.post("/register", api.handleregister) router.get("/getcookie", api.getcookiesession) router.get("/books", api.getbooksapi) router.get("/books/:id", api.bookbyidapi) router.patch("/rent/:id", api.rentbookapi) router.patch("/return/:id", api.returnbookapi) router.run("localhost:3000") }
Voici le frontend :
import axios from 'axios' const url = 'http://localhost:3000' export const loginuser = async (credentials) => await axios.post(`${url}/login`, credentials, {withcredentials: true}) export const logoutuser = async () => await axios.get(`${url}/logout`, {withcredentials: true}) export const registeruser = () => axios.post(`${url}/register`) export const fetchbooks = () => axios.get(`${url}/books`, { withcredentials: true }) export const fetchbookbyid = (book_id) => axios.get(`${url}/books/${book_id}`, { withcredentials: true }) export const rentbook = (book_id) => axios.patch(`${url}/rent/${book_id}`, { withcredentials: true }) export const returnbook = (book_id) => axios.patch(`${url}/return/${book_id}`, { withcredentials: true })
Je suis presque sûr d'avoir configuré correctement le backend et il devrait renvoyer tous les en-têtes nécessaires.
Par exemple, pour une requête get, les en-têtes de réponse ressemblent à ceci :
http/1.1 200 ok access-control-allow-credentials: true access-control-allow-headers: content-type, authorization access-control-allow-methods: get, post, put, delete, patch, options access-control-allow-origin: http://localhost:3001 content-type: application/json; charset=utf-8 date: sat, 10 jun 2023 22:12:11 gmt content-length: 495
Cependant, pour la tentative de demande de correctif, je ne reçois aucune réponse (sans surprise) et les en-têtes de réponse en amont sont :
http/1.1 200 ok date: sat, 10 jun 2023 22:12:12 gmt content-length: 0
Avez-vous des suggestions sur d'éventuels problèmes ? Après ces deux jours, je n’en ai aucune idée. Merci d'avance!
J'ai aussi essayé d'ajouter un titre :
c.writer.header().set("access-control-allow-origin", host) c.writer.header().set("access-control-allow-credentials", "true") c.writer.header().set("access-control-allow-headers", "content-type, authorization") c.writer.header().set("access-control-allow-methods", "get, post, put, delete, patch, options")
...encore une fois dans l'instruction if :
if c.request.method == "options" { log.println("handling options request") c.abortwithstatus(http.statusnocontent) return }
Mais ça n’aide pas du tout. En fait, si l'instruction n'est pas exécutée lorsque le contrôle en amont est exécuté, je sais depuis la console que le serveur exécute la demande d'options.
[gin] 2023/06/11 - 00:12:13 | 200 | 7.708µs | 127.0.0.1 | options "/rent/2"
Éditeur :
C'est la commande curl qui envoie la demande de correctif (il s'agit donc en fait de la demande d'options de contrôle en amont) :
curl 'http://localhost:3000/return/2' \ -x 'options' \ -h 'accept: */*' \ -h 'accept-language: en-us,en;q=0.9,pl-pl;q=0.8,pl;q=0.7' \ -h 'access-control-request-headers: content-type' \ -h 'access-control-request-method: patch' \ -h 'cache-control: no-cache' \ -h 'connection: keep-alive' \ -h 'origin: http://localhost:3001' \ -h 'pragma: no-cache' \ -h 'referer: http://localhost:3001/' \ -h 'sec-fetch-dest: empty' \ -h 'sec-fetch-mode: cors' \ -h 'sec-fetch-site: same-site' \ -h 'user-agent: mozilla/5.0 (macintosh; intel mac os x 10_15_7) applewebkit/537.36 (khtml, like gecko) chrome/114.0.0.0 safari/537.36' \ --compressed
Réponse à cette demande :
HTTP/1.1 200 OK Date: Sun, 11 Jun 2023 01:22:57 GMT Content-Length: 0
Il s'avère que vous utilisez la configuration de démonstration d'un package obsolète github.com/gin-gonic/contrib/cors
。您应该使用 github.com/gin-contrib/cors
代替。这是使用 github.com/gin-contrib/cors
:
package main import ( "github.com/gin-contrib/cors" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" ) func main() { router := gin.default() config := cors.defaultconfig() config.addallowheaders("authorization") config.allowcredentials = true config.allowallorigins = false // i think you should whitelist a limited origins instead: // config.allowallorigins = []{"xxxx", "xxxx"} config.alloworiginfunc = func(origin string) bool { return true } router.use(cors.new(config)) store := cookie.newstore([]byte("your-secret-key")) store.options(sessions.options{maxage: 60 * 60 * 24}) router.use(sessions.sessions("sessions", store)) // routes below router.run("localhost:3000") }
Pour une raison quelconque, patch
请求标头缺少“cookie”标头,尽管我使用了 withcredentials
paramètres.
axios.patch(`${url}/rent/${book_id}`, { withcredentials: true })
Ici { withcredentials: true }
est traité comme une donnée et n'a aucune configuration. Si vous n'avez aucune donnée à envoyer au serveur, vous devez écrire comme ceci :
axios.patch(`${url}/rent/${book_id}`, null, { withCredentials: true })
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!