web-dev-qa-db-ja.com

HTTPヘッダーの設定

Go Webサーバーにヘッダーを設定しようとしています。 gorilla/muxおよびnet/httpパッケージを使用しています。

Access-Control-Allow-Origin: *を設定して、クロスドメインAJAXを許可します。

Goコードは次のとおりです。

func saveHandler(w http.ResponseWriter, r *http.Request) {
// do some stuff with the request data
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/save", saveHandler)
    http.Handle("/", r)
    http.ListenAndServe(":"+port, nil)
}

net/httpパッケージには、httpリクエストヘッダーをクライアントであるかのように送信することを説明したドキュメントがあります。応答ヘッダーの設定方法が正確にわかりません。

152
Zen

気にせず、私はそれを理解しました-Set()Header()メソッドを使用しました(doh!)

ハンドラーは次のようになります。

func saveHandler(w http.ResponseWriter, r *http.Request) {
    // allow cross domain AJAX requests
    w.Header().Set("Access-Control-Allow-Origin", "*")
}

たぶん、これはいつか自分のようにカフェインを奪われた誰かを助けるでしょう:)

204
Zen

上記の回答はすべて、OPTIONSプリフライトリクエストの処理に失敗するため間違っています。解決策は、muxルーターのインターフェイスをオーバーライドすることです。 AngularJS $ http get request failed with custom header(allows in CORS) を参照してください

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/save", saveHandler)
    http.Handle("/", &MyServer{r})
    http.ListenAndServe(":8080", nil);

}

type MyServer struct {
    r *mux.Router
}

func (s *MyServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
    if Origin := req.Header.Get("Origin"); Origin != "" {
        rw.Header().Set("Access-Control-Allow-Origin", Origin)
        rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        rw.Header().Set("Access-Control-Allow-Headers",
            "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
    }
    // Stop here if its Preflighted OPTIONS request
    if req.Method == "OPTIONS" {
        return
    }
    // Lets Gorilla work
    s.r.ServeHTTP(rw, req)
}
98
Matt Bucci

完全にパブリックな動作が本当に必要になるまで、Originに「*」を使用しないでください。
As ウィキペディアによると

「「*」の値は、HTTP認証、クライアント側のSSL証明書を意味する要求の資格情報の提供を許可せず、Cookieの送信を許可しないという点で特別です。」

つまり、たとえば単純な認証を実装しようとすると、特にChromeで多くのエラーが発生します。

修正されたラッパーは次のとおりです。

// Code has not been tested.
func addDefaultHeaders(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        if Origin := r.Header.Get("Origin"); Origin != "" {
            w.Header().Set("Access-Control-Allow-Origin", Origin)
        }
        w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token")
        w.Header().Set("Access-Control-Allow-Credentials", "true")
        fn(w, r)
    }
}

そして、これらすべてのヘッダーをプリフライトOPTIONSリクエストに返信することを忘れないでください。

22
tacobot

適切なgolangミドルウェアを設定して、任意のエンドポイントで再利用できるようにします。

ヘルパーのタイプと機能

type Adapter func(http.Handler) http.Handler
// Adapt h with all specified adapters.
func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
    for _, adapter := range adapters {
        h = adapter(h)
    }
    return h
}

実際のミドルウェア

func EnableCORS() Adapter {
    return func(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

            if Origin := r.Header.Get("Origin"); Origin != "" {
                w.Header().Set("Access-Control-Allow-Origin", Origin)
                w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
                w.Header().Set("Access-Control-Allow-Headers",
                    "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
            }
            // Stop here if its Preflighted OPTIONS request
            if r.Method == "OPTIONS" {
                return
            }
            h.ServeHTTP(w, r)
        })
    }
}

終点

覚えて!ミドルウェアは逆順で適用されます(ExpectGET()が最初に起動します)

mux.Handle("/watcher/{action}/{device}",Adapt(api.SerialHandler(mux),
    api.EnableCORS(),
    api.ExpectGET(),
))
13
CESCO

この場合のラッパーを作成します。

func addDefaultHeaders(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        fn(w, r)
    }
}
12
obyknovenius

ルーターをオーバーライドしたくない場合(これをサポートするようにアプリを構成していない場合、またはルートごとにCORSを構成する場合)、OPTIONSを追加しますフライト前のリクエストを処理するハンドラ。

つまり、Gorilla Muxを使用すると、ルートは次のようになります。

accounts := router.Path("/accounts").Subrouter()
accounts.Methods("POST").Handler(AccountsCreate)
accounts.Methods("OPTIONS").Handler(AccountsCreatePreFlight)

上記のPOSTハンドラーに加えて、特定のOPTIONSメソッドハンドラーを定義していますに注意してください。

そして、OPTIONSプリフライトメソッドを実際に処理するには、次のようにAccountsCreatePreFlightを定義できます。

// Check the Origin is valid.
Origin := r.Header.Get("Origin")
validOrigin, err := validateOrigin(Origin)
if err != nil {
    return err
}

// If it is, allow CORS.
if validOrigin {
    w.Header().Set("Access-Control-Allow-Origin", Origin)
    w.Header().Set("Access-Control-Allow-Methods", "POST")
    w.Header().Set("Access-Control-Allow-Headers",
        "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}

実際にこれをすべてクリックさせたのは(CORSの仕組みを実際に理解することに加えて)、プリフライトリクエストのHTTPメソッドは実際のリクエストのHTTPメソッドとは異なります CORSを開始するには、ブラウザはHTTPメソッドOPTIONSを使用してプリフライトリクエストを送信します。これはルーターで明示的に処理する必要があり、アプリケーションから適切な応答"Access-Control-Allow-Origin": Origin(または「*」)を受信すると、実際のリクエストを開始します。

また、標準タイプのリクエスト(つまり、GET)に対してのみ「*」を実行できると考えていますが、他の場合は、上記のようにOriginを明示的に設定する必要があります。

10
Kyle Chadha

上記と同じ問題がありました。上記の解決策は正しいです。設定は次のとおりです。1)クライアント用のAngularjs 2)GOサーバー用のBeegoフレームワーク

これらのポイントに従ってください1)CORS設定はGOサーバーでのみ有効にする必要があります2)これ以外のタイプのヘッダーをangleJSに追加しないでください

.config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.useXDomain = true;
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
    }])

GOサーバーで、プリフライトリクエストが200 OKを受信できるように、リクエストの処理を開始する前にCORS設定を追加します。その後、OPTIONSメソッドはGET、POST、PUTまたはリクエストタイプに変換されます。

1
Prostil Hardi