CORS-Richtlinie: Antwort auf Preflight-Anfrage schlägt bei der Zugriffskontrollprüfung fehl: Nein „Access-Control-Allow-Origin'

王林
Freigeben: 2024-02-06 11:00:08
nach vorne
750 Leute haben es durchsucht

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

Frageninhalt

Ich verwende Golang und Gin-Gonic/Gin Web Framework im Backend und reagiere auf Axios im Frontend. Ich habe zwei Tage lang versucht, das Problem zu lösen, und es wird immer noch die gleiche Fehlermeldung angezeigt:

cors policy: response to preflight request doesn't pass access control check: no 'access-control-allow-origin' header is present on the requested resource.
Nach dem Login kopieren

Dieser Fehler tritt nur auf, wenn ich versuche, eine Patch-Anfrage zu senden, sodass diese Anfrage eine Anfrage nach Preflight-Optionen erfordert, aber alles mit get und post funktioniert wie erwartet, es werden keine Preflight-Prüfungen durchgeführt.

Das ist der Code für meine Router-Konfiguration:

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")
}
Nach dem Login kopieren

Das ist das 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 })
Nach dem Login kopieren

Ich bin mir ziemlich sicher, dass ich das Backend richtig eingerichtet habe und es alle notwendigen Header zurückgeben sollte.

Für eine Get-Anfrage sehen die Antwortheader beispielsweise so aus:

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
Nach dem Login kopieren

Obwohl ich auf den Patch-Request-Versuch keine Antwort bekomme (was nicht überraschend ist) und die Preflight-Antwortheader lauten:

http/1.1 200 ok
date: sat, 10 jun 2023 22:12:12 gmt
content-length: 0
Nach dem Login kopieren

Haben Sie Vorschläge für mögliche Probleme? Nach diesen zwei Tagen habe ich keine Ahnung mehr. Vielen Dank im Voraus!

Ich habe auch versucht, einen Titel hinzuzufügen:

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")
Nach dem Login kopieren

...wieder in der if-Anweisung:

if c.request.method == "options" {
    log.println("handling options request")
    c.abortwithstatus(http.statusnocontent)
    return
    }
Nach dem Login kopieren

Aber das hilft überhaupt nicht. Tatsächlich wird diese If-Anweisung nicht ausgeführt, wenn der Preflight ausgeführt wird. Ich weiß von der Konsole, dass der Server die Optionsanforderung ausführt.

[gin] 2023/06/11 - 00:12:13 | 200 |       7.708µs |       127.0.0.1 | options  "/rent/2"
Nach dem Login kopieren

Herausgeber:

Dies ist der Curl-Befehl, der die Patch-Anfrage sendet (also eigentlich die Preflight-Optionsanfrage):

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
Nach dem Login kopieren

Antwort auf diese Anfrage:

HTTP/1.1 200 OK
Date: Sun, 11 Jun 2023 01:22:57 GMT
Content-Length: 0
Nach dem Login kopieren


Richtige Antwort


Es stellt sich heraus, dass Sie die Demokonfiguration eines veralteten Pakets verwenden 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")
}
Nach dem Login kopieren

Aus irgendeinem Grund patch 请求标头缺少“cookie”标头,尽管我使用了 withcredentials Parameter.

axios.patch(`${url}/rent/${book_id}`, { withcredentials: true })
Nach dem Login kopieren

Hier { withcredentials: true } wird als Daten behandelt und hat keine Konfiguration. Wenn Sie keine Daten zum Senden an den Server haben, sollten Sie so schreiben:

axios.patch(`${url}/rent/${book_id}`, null, { withCredentials: true })
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonCORS-Richtlinie: Antwort auf Preflight-Anfrage schlägt bei der Zugriffskontrollprüfung fehl: Nein „Access-Control-Allow-Origin'. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!