Go 웹 서버에서 헤더를 설정하려고합니다. 패키지를 사용 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 요청 헤더를 보내는 기술 문서를 가지고?
답변
신경 쓰지 마, 알아 냈어-나는 Set()
방법을 사용했다 .Header()
.
내 핸들러는 이제 다음과 같습니다.
func saveHandler(w http.ResponseWriter, r *http.Request) {
// allow cross domain AJAX requests
w.Header().Set("Access-Control-Allow-Origin", "*")
}
어쩌면 이것은 때때로 나 자신처럼 박탈당한 카페인으로 누군가를 도울 것입니다 🙂
답변
위의 모든 답변은 OPTIONS 사전 비행 요청을 처리하지 못하기 때문에 잘못되었습니다. 해결책은 mux 라우터의 인터페이스를 재정의하는 것입니다. 커스텀 헤더로 실패한 AngularJS $ http get 요청을 참조하십시오 (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)
}
답변
완전히 공개적인 행동이 필요할 때까지 Origin에 ‘*’를 사용하지 마십시오. Wikipedia는 다음과
같이 말합니다 .
“*”의 값은 요청이 HTTP 인증, 클라이언트 측 SSL 인증서를 의미하는 자격 증명을 제공 할 수 없으며 쿠키를 보낼 수 없다는 점에서 특별합니다. “
즉, 간단한 인증과 같은 구현을 시도 할 때 특히 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 요청에이 헤더를 모두 회신하는 것을 잊지 마십시오.
답변
적절한 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(),
))
답변
라우터를 재정의하지 않으려는 경우 경우 (이를 지원하는 방식으로 앱을 구성하지 않았거나 경로별로 경로에 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)에 대해서만 “*”를 수행 할 수 있다고 생각하지만 다른 경우에는 위에서처럼 원점을 명시 적으로 설정해야합니다.
답변
이 경우 래퍼를 만듭니다.
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)
}
}
답변
위에서 설명한 것과 동일한 문제가 발생했습니다. 위의 솔루션이 정확합니다. 설정은 다음과 같습니다 .1) 클라이언트의 Angularjs 2) GO 서버의 Beego 프레임 워크
다음 사항을 준수하십시오. 1) CORS 설정은 GO 서버에서만 활성화해야합니다. 2) angularJS에 헤더 유형을 추가하지 마십시오.
.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}])
GO 서버에서 요청 처리가 시작되기 전에 CORS 설정을 추가하여 프리 플라이트 요청이 200 OK를 수신 한 후 OPTIONS 메소드가 GET, POST, PUT 또는 요청 유형을 변환합니다.