Maison  >  Article  >  développement back-end  >  Politique CORS : la réponse à la demande de contrôle en amont échoue à la vérification du contrôle d'accès : non "Access-Control-Allow-Origin"

Politique CORS : la réponse à la demande de contrôle en amont échoue à la vérification du contrôle d'accès : non "Access-Control-Allow-Origin"

王林
王林avant
2024-02-06 11:00:08726parcourir

CORS 策略:对预检请求的响应未通过访问控制检查:无“Access-Control-Allow-Origin”

Contenu de la question

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

Bonne réponse


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!

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