首頁 > 後端開發 > Golang > Golang 應用程式:請求的資源上不存在「Access-Control-Allow-Origin」標頭

Golang 應用程式:請求的資源上不存在「Access-Control-Allow-Origin」標頭

王林
發布: 2024-02-06 09:18:03
轉載
1017 人瀏覽過

Golang 应用程序:请求的资源上不存在“Access-Control-Allow-Origin”标头

問題內容

每當我嘗試從 Angular 應用程式向 Go 伺服器發送 HTTP 請求時,我都會收到以下回應:

對預檢請求的回應未通過存取控制檢查:請求的資源上不存在「Access-Control-Allow-Origin」標頭。

我添加了錯誤回應中詳細說明的標頭,但錯誤仍然存在。

伺服器.go

package rest

import (
    "context"
    "fmt"
    "net/http"
    "os"
    "os/signal"
    "sync"
    "syscall"

    "github.com/gorilla/mux"
    "github.com/randyVerduguez/randy-verduguez_06122023-BE-challenge/configs"
    "github.com/randyVerduguez/randy-verduguez_06122023-BE-challenge/http/rest/handlers"
    "github.com/randyVerduguez/randy-verduguez_06122023-BE-challenge/pkg/db"
    "github.com/rs/cors"
    "github.com/sirupsen/logrus"
)

type Server struct {
    logger *logrus.Logger
    router *mux.Router
    config configs.Config
}

func NewServer() (*Server, error) {
    config, err := configs.NewParsedConfig()

    if err != nil {
        return nil, err
    }

    database, err := db.Connect(db.ConfigDB{
        Host:     config.Database.Host,
        Port:     config.Database.Port,
        User:     config.Database.User,
        Password: config.Database.Password,
        Name:     config.Database.Name,
    })

    if err != nil {
        return nil, err
    }

    log, err := NewLogger()

    if err != nil {
        return nil, err
    }

    router := mux.NewRouter()

    handlers.Register(router, log, database)

    server := Server{
        logger: log,
        config: config,
        router: router,
    }

    return &server, nil
}

func (s *Server) Run(ctx context.Context) error {
    cors := cors.New(cors.Options{
        AllowedMethods: []string{"GET, POST"},
        AllowedOrigins: []string{"http://localhost:4200"},
        AllowedHeaders: []string{"Content-Type", "Accept"},
    })

    server := http.Server{
        Addr:    fmt.Sprintf(":%d", s.config.ServerPort),
        Handler: cors.Handler(s.router),
    }

    stopServer := make(chan os.Signal, 1)

    signal.Notify(stopServer, syscall.SIGINT, syscall.SIGTERM)

    defer signal.Stop(stopServer)

    serverErrors := make(chan error, 1)

    var wg sync.WaitGroup
    wg.Add(1)

    go func(wg *sync.WaitGroup) {
        defer wg.Done()
        s.logger.Printf("REST API listening on  %d", s.config.ServerPort)
        serverErrors <- server.ListenAndServe()
    }(&wg)

    select {
    case err := <-serverErrors:
        return fmt.Errorf("error: starting REST API server %w", err)
    case <-stopServer:
        s.logger.Warn("server recieved STOP signal")

        err := server.Shutdown(ctx)

        if err != nil {
            return fmt.Errorf("graceful shutdown did not complete: %w", err)
        }

        wg.Wait()
        s.logger.Info("server was shutdown gracefully")
    }

    return nil
}

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "http://localhost:4200")
    w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
    w.Header().Set("Access-Control-Allow-Credentials", "true")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, Accept, origin, Cache-Control, X-Requested-With")

    if r.Method == "OPTIONS" {
        return
    }

    s.router.ServeHTTP(w, r)
}
登入後複製

路線.go

package handlers

import (
    "net/http"

    "github.com/gorilla/mux"
    "github.com/jmoiron/sqlx"
    "github.com/sirupsen/logrus"
)

func Register(r *mux.Router, lg *logrus.Logger, db *sqlx.DB) {
    handler := newHandler(lg, db)

    r.Use(handler.MiddlewareLogger())
    r.HandleFunc("/weather/current", handler.GetCurrentWeather()).Methods(http.MethodPost)
    r.HandleFunc("/weather/welcome", handler.Test()).Methods(http.MethodGet)
}
登入後複製


正確答案


我注意到的第一個問題是:

AllowedMethods: []string{"GET, POST"},

#這應該是:

AllowedMethods: []string{"GET", "POST"}, (或稍微不易出錯的[]string{http.MethodGet, http.MethodPost})

根據文件,這是預設值(所以你可以省略它) :

我的下一個問題是“起源是什麼”; CORS 是“跨來源資源共享”,旨在 “防止從一個來源運行的客戶端Web 應用程式獲取從另一個來源檢索的數據”,因此了解發出請求的頁面的來源非常重要。您允許http://localhost:4200 (AllowedOrigins: []string{"http://localhost:4200"}) 所以我假設您有兩個伺服器在本地主機上運行(但如果這不是案件)。如果您希望允許所有來源,請使用"*";為了進行測試,我將使用test-cors.org - 只需前往該網站,輸入URL,例如“ http://127.0.0.1:8080/weather/welcome”,進入“遠端URL”,點擊“發送請求”進行測試。

您的程式碼有點令人困惑(例如(s *Server) ServeHTTP 未使用- 請旨在提供最小,可重現的範例,當在這裡提問時),所以我稍微簡化了一些事情,希望以下內容能為您指明正確的方向。

package main

import (
    "context"
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
    "github.com/rs/cors"
)

func main() {
    s, err := NewServer()
    if err != nil {
        panic(err)
    }
    s.Run(context.Background())
}

type Server struct {
    router *mux.Router
}

func NewServer() (*Server, error) {
    router := mux.NewRouter()
    Register(router)
    server := Server{
        router: router,
    }
    return &server, nil
}

func (s *Server) Run(ctx context.Context) {
    cors := cors.New(cors.Options{
        AllowedMethods: []string{http.MethodGet, http.MethodPost},
        AllowedOrigins: []string{"https://www.php.cn/link/9113c52c5f26af1782e6bf7c56973ef4"},
        // AllowedOrigins: []string{"*"},
        AllowedHeaders: []string{"Content-Type", "Accept"},
    })

    server := http.Server{
        Addr:    fmt.Sprintf(":%d", 8080),
        Handler: cors.Handler(s.router),
    }

    fmt.Println(server.ListenAndServe())
}

type handler struct{}

func Register(r *mux.Router) {
    handler := handler{}

    r.HandleFunc("/", handler.Index).Methods(http.MethodGet)
    r.HandleFunc("/weather/welcome", handler.Test).Methods(http.MethodGet)
}

// Index - Provide a simple page with a link to the other page to simplify testing
func (h *handler) Index(w http.ResponseWriter, _ *http.Request) {
    w.Write([]byte(`<a href="weather/welcome" >Test Link</a>`))
}

// The real page
func (h *handler) Test(w http.ResponseWriter, _ *http.Request) {
    fmt.Println("Test Called")
    w.Write([]byte("all OK"))
}
登入後複製

以上是Golang 應用程式:請求的資源上不存在「Access-Control-Allow-Origin」標頭的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板