Ustawianie nagłówków HTTP

Próbuję ustawić nagłówek na moim serwerze WWW Go. Używam pakietów gorilla/mux i net/http.

Chciałbym ustawić Access-Control-Allow-Origin: * aby zezwalać na cross domain AJAX.

Oto Mój kod:

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

Pakiet net/http posiada dokumentację opisującą wysyłanie nagłówków żądań http tak, jakby był klientem - nie jestem do końca pewien jak ustawić nagłówki odpowiedzi?

Author: Flimzy, 2012-10-11

8 answers

Nieważne, rozgryzłem to - użyłem metody Set() na Header() (doh!)

Mój opiekun wygląda teraz tak:

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

Może to kiedyś pomoże komuś tak pozbawionemu kofeiny jak ja:)

 191
Author: Zen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-10 23:46:18

Wszystkie powyższe odpowiedzi są błędne, ponieważ nie obsługują żądania preflight opcji, rozwiązaniem jest nadpisanie interfejsu routera mux. Zobacz AngularJS $ http GET request failed with custom header (alllowed 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)
}
 93
Author: Matt Bucci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:53

Nie używaj '*' Dla Origin, dopóki naprawdę nie potrzebujesz całkowicie publicznego zachowania.
Jak mówi Wikipedia :

"wartość" * " jest szczególna, ponieważ nie pozwala żądaniom dostarczenia danych uwierzytelniających, oznacza uwierzytelnianie HTTP, certyfikaty SSL po stronie klienta, ani nie zezwala na pliki cookie do wysłania."

Oznacza to, że pojawi się wiele błędów, szczególnie w Chrome, gdy spróbujesz zaimplementować na przykład proste uwierzytelnianie.

Oto poprawione opakowanie:

// 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)
    }
}

I nie zapomnij odpowiedzieć na wszystkie te nagłówki na żądanie opcji inspekcji wstępnej.

 22
Author: tacobot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-22 22:44:17

Tworzę wrapper dla tego przypadku:

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
Author: obyknovenius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-08 18:06:25

Ustaw odpowiednie oprogramowanie pośrednie golang, abyś mógł ponownie użyć dowolnego punktu końcowego.

Helper Type and Function

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
}

Actual middleware

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

Punkt końcowy

REMEBER! Middlewares get applyed on reverse order (ExpectGET () gets fires first)

mux.Handle("/watcher/{action}/{device}",Adapt(api.SerialHandler(mux),
    api.EnableCORS(),
    api.ExpectGET(),
))
 12
Author: CESCO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-10 12:25:16

Jeśli nie chcesz zastąpić routera (jeśli nie masz skonfigurowanej aplikacji w sposób, który to obsługuje, lub chcesz skonfigurować CORS na podstawie trasy po trasie), dodaj obsługę opcji do obsługi żądania przed lotem.

Ie, z Gorilla Mux Twoje trasy wyglądałyby następująco:

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

Zauważ powyżej, że oprócz naszego programu obsługi poczty, definiujemy konkretną metodę obsługi opcji .

A następnie, aby faktycznie obsłużyć metodę options preflight, należy można zdefiniować AccountsCreatePreFlight tak:

// 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")
}

To, co naprawdę sprawiło, że to wszystko kliknęło dla mnie (oprócz faktycznego zrozumienia, jak działa CORS), to to, że metoda HTTP żądania wstępnego różni się od metody HTTP rzeczywistego żądania. aby zainicjować CORS, przeglądarka wysyła żądanie inspekcji wstępnej z opcjami metody HTTP, które musisz obsłużyć jawnie w routerze, a następnie, jeśli otrzyma odpowiednią odpowiedź "Access-Control-Allow-Origin": origin (lub "*" dla wszystkich) z Twojego routera aplikacja, inicjuje rzeczywiste żądanie.

Wierzę również, że możesz zrobić tylko "*" dla standardowych typów żądań (ie: GET), ale dla innych będziesz musiał wyraźnie ustawić pochodzenie, tak jak to robię powyżej.

 10
Author: Kyle Chadha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-12 23:49:50

Miałem ten sam problem jak wyżej opisane rozwiązania podane powyżej są poprawne, konfiguracja jaką mam jest następująca 1) Angularjs dla Klienta 2) beego framework for GO server

Proszę postępować zgodnie z tymi punktami 1) Ustawienia CORS muszą być włączone tylko na serwerze GO 2) nie dodawaj żadnych nagłówków w angularJS z wyjątkiem tego

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

In you go server Dodaj Ustawienia CORS, zanim żądanie zacznie być przetwarzane, aby żądanie inspekcji wstępnej otrzymało 200 OK, po czym metoda OPTIONS zostanie przekonwertowana na GET, POST,PUT lub inny typ żądania.

 1
Author: Prostil Hardi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-02 08:42:31

Wiem, że to inny zwrot w odpowiedzi, ale czy nie jest to bardziej problem dla serwera www? Na przykład, nginx, może pomóc.

Moduł ngx_http_headers_module umożliwia dodawanie pól nagłówka" Expires "i" Cache-Control " oraz dowolnych pól do nagłówka odpowiedzi

...

location ~ ^<REGXP MATCHING CORS ROUTES> {
    add_header Access-Control-Allow-Methods POST
    ...
}
...
Dzięki temu możesz mieć pewność, że Twoje dane osobowe będą przetwarzane w sposób zgodny z prawem. Zapewnia o wiele więcej funkcji do autoryzacji,rejestrowania i modyfikowania prośby. Ponadto daje możliwość kontrolowania, kto ma dostęp do usługi, a nie tylko to, ale można określić różne zachowanie dla określonych lokalizacji w aplikacji, jak pokazano powyżej.

Mógłbym mówić o tym, dlaczego używać serwera www z API go, ale myślę, że to temat do innej dyskusji.

 -7
Author: shwoodard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-04 12:59:03