HTTP शीर्षलेख सेट करना




http-headers go (6)

उचित गोलांग मिडलवेयर सेट करें, ताकि आप किसी भी एंडपॉइंट पर पुन: उपयोग कर सकें।

सहायक प्रकार और समारोह

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

endpoint

याद! मिडलवायर रिवर्स ऑर्डर पर लागू होते हैं (एक्सपेक्ट जीईटी () पहले आग लगती है)

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

मैं अपने गो वेब सर्वर में एक शीर्षलेख सेट करने की कोशिश कर रहा हूं। मैं gorilla/mux और net/http पैकेज का उपयोग कर रहा हूं।

मैं क्रॉस डोमेन AJAX को अनुमति देने के लिए Access-Control-Allow-Origin: * सेट करना चाहता हूं Access-Control-Allow-Origin: *

मेरा गो कोड यहां दिया गया है:

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 अनुरोध हेडर भेजने का वर्णन करने वाले दस्तावेज़ हैं जैसे कि यह क्लाइंट था - मुझे बिल्कुल सही नहीं है कि प्रतिक्रिया शीर्षलेख कैसे सेट करें?


उत्पत्ति के लिए '*' का उपयोग न करें, जब तक कि आपको वास्तव में पूरी तरह से सार्वजनिक व्यवहार की आवश्यकता न हो।
विकिपीडिया कहता है :

"* *" का मान विशेष है कि यह प्रमाण-पत्रों को प्रमाणित करने की अनुमति नहीं देता है, जिसका अर्थ है HTTP प्रमाणीकरण, क्लाइंट-साइड SSL प्रमाणपत्र, और न ही यह कुकीज़ को भेजने की अनुमति देता है। "

इसका मतलब है, आपको बहुत सारी त्रुटियां मिलेंगी, खासकर क्रोम में जब आप कार्यान्वित करने का प्रयास करेंगे उदाहरण के लिए एक सरल प्रमाणीकरण।

यहां एक सही रैपर है:

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

और इन सभी शीर्षकों को प्रीफलाइट विकल्प अनुरोधों को उत्तर देना न भूलें।


कोई बात नहीं, मैंने इसे समझ लिया - मैंने Header() ( Set() पर Set() विधि का उपयोग किया

मेरा हैंडलर अब इस तरह दिखता है:

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

शायद यह किसी के रूप में कैफीन वंचित होने में मदद करेगा :)


मुझे पता है कि यह उत्तर पर एक अलग मोड़ है, लेकिन यह वेब सर्वर के लिए चिंता का अधिक नहीं है? उदाहरण के लिए, nginx , मदद कर सकता है।

Ngx_http_headers_module मॉड्यूल एक प्रतिक्रिया शीर्षलेख में "समाप्ति" और "कैश-कंट्रोल" शीर्षलेख फ़ील्ड, और मनमानी फ़ील्ड जोड़ने की अनुमति देता है

...

location ~ ^<REGXP MATCHING CORS ROUTES> {
    add_header Access-Control-Allow-Methods POST
    ...
}
...

उत्पादन में अपनी जाने वाली सेवा के सामने nginx जोड़ना बुद्धिमान लगता है। यह अनुरोधों को अधिकृत करने, लॉगिंग करने और संशोधित करने के लिए बहुत अधिक सुविधा प्रदान करता है। साथ ही, यह नियंत्रित करने की क्षमता देता है कि किसके पास आपकी सेवा तक पहुंच है और न केवल यह कि कोई भी आपके ऐप में विशिष्ट स्थानों के लिए अलग-अलग व्यवहार निर्दिष्ट कर सकता है, जैसा ऊपर दिखाया गया है।

मैं आपके गो एपीआई के साथ एक वेब सर्वर का उपयोग क्यों कर सकता हूं, लेकिन मुझे लगता है कि यह एक और चर्चा के लिए एक विषय है।


मैं इस मामले के लिए रैपर बनाते हैं:

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

यदि आप अपने राउटर को ओवरराइड नहीं करना चाहते हैं (क्योंकि हम में से कई हमारे ऐप्स को इस तरह से कॉन्फ़िगर नहीं करते हैं, या बस मार्ग के आधार पर मार्ग पर सीओआरएस कॉन्फ़िगर करना चाहते हैं), तो पूर्व उड़ान अनुरोध को संभालने के लिए बस एक विकल्प हैंडलर जोड़ें ।

हां, गोरिल्ला मक्स के साथ आपके मार्ग इस तरह दिखेगा:

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

ऊपर पोस्ट करें कि हमारे पोस्ट हैंडलर के अतिरिक्त, हम एक विशिष्ट विकल्प विधि हैंडलर को परिभाषित कर रहे हैं

और उसके बाद 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")
}

वास्तव में यह सब मेरे लिए क्या क्लिक करता है (वास्तव में यह समझने के अलावा कि सीओआरएस कैसे काम करता है) यह है कि प्रीफलाइट अनुरोध का HTTP विधि वास्तविक अनुरोध के HTTP विधि से अलग है। सीओआरएस शुरू करने के लिए, ब्राउजर HTTP विधि विकल्प के साथ एक प्रीफलाइट अनुरोध भेजता है, जिसे आपको अपने राउटर में स्पष्ट रूप से संभालना होता है, और फिर, यदि उसे उपयुक्त "Access-Control-Allow-Origin": origin (या "*" सभी के लिए) आपके आवेदन से, यह वास्तविक अनुरोध शुरू करता है।

मुझे यह भी विश्वास है कि आप मानक प्रकार के अनुरोधों (यानी: जीईटी) के लिए केवल "*" कर सकते हैं, लेकिन दूसरों के लिए आपको स्पष्ट रूप से मूल जैसा सेट करना होगा जैसा मैं ऊपर करता हूं।





go