ホームページ  >  記事  >  バックエンド開発  >  Golang アプリケーション: 要求されたリソースに「Access-Control-Allow-Origin」ヘッダーが存在しません

Golang アプリケーション: 要求されたリソースに「Access-Control-Allow-Origin」ヘッダーが存在しません

王林
王林転載
2024-02-06 09:18:03982ブラウズ

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

質問の内容

Angular アプリケーションから Go サーバーに HTTP リクエストを送信しようとすると、次のような応答が返されます。

プリフライト要求への応答はアクセス制御チェックに失敗しました: 'Access-Control-Allow-Origin' ヘッダーが要求されたリソースに存在しません。

エラー応答に詳細に記載されているヘッダーを追加しましたが、エラーは引き続き発生します。

server.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)
}


正解


私が気づいた最初の質問は次のとおりです:

許可されたメソッド: []string{"GET, POST"},

これはおそらく次のとおりです:

AllowedMethods: []string{"GET", "POST"}, (またはエラーが発生しにくい []string{http.MethodGet, http.MethodPost} )

ドキュメント

によると、これはデフォルト値です (したがって省略できます): 次の質問は「オリジンとは何ですか」です。CORS は「クロスオリジン リソース共有」であり、

「あるオリジンから実行されているクライアント Web アプリケーションが別のオリジン データから取得されないようにする」ように設計されています。したがって、リクエストを行っているページのソースを知ることが重要です。 http://localhost:4200 (AllowedOrigins: []string{"http://localhost:4200"}) を許可しているので、localhost 上に 2 つのサーバーが実行されていると仮定します。 (ただし、そうでない場合)。すべてのオリジンを許可したい場合は、"*" を使用します。テストには、test-cors.org を使用します。Web サイトにアクセスし、URL を入力します。例: " http://127.0.0.1:8080/weather/welcome」に「リモート URL」を入力し、「リクエストの送信」をクリックしてテストします。 あなたのコードは少し混乱しています (例:

(s *Server) ServeHTTP

は使用されていません - ここで質問するときは、最小限で再現可能な例を提供するようにしてください)。物事を少し単純化しましたが、次の内容が正しい方向に役立つことを願っています。 リーリー

以上がGolang アプリケーション: 要求されたリソースに「Access-Control-Allow-Origin」ヘッダーが存在しませんの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。