HTTP শিরোনাম সেট করা হচ্ছে


165

আমি আমার গো ওয়েব সার্ভারে একটি শিরোনাম সেট করার চেষ্টা করছি। আমি gorilla/muxএবং net/httpপ্যাকেজ ব্যবহার করছি ।

আমি 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 অনুরোধ হেডার পাঠানোর বর্ণনা আছে?

উত্তর:


227

কিছু মনে করবেন না, আমি এটি বুঝতে পেরেছি - আমি Set()পদ্ধতিটি ব্যবহার করেছিHeader() (দোহ!)

আমার হ্যান্ডলারটি এখন এর মতো দেখাচ্ছে:

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

হতে পারে এটি কাউকে আমার মাঝে বঞ্চিত ক্যাফিন হিসাবে সাহায্য করবে :)


2
আমি একই সমস্যাটি করছি, এটি যুক্ত করতেও সহায়ক হতে পারে: w.Header().Add("Access-Control-Allow-Methods", "PUT") w.Header().Add("Access-Control-Allow-Headers", "Content-Type")
রে

1
এজেএক্স ক্লায়েন্ট সেট হওয়ার ক্ষেত্রে এটি কাজ করবে না withCredentials:true(শংসাপত্র প্রেরণের সময় "*" মান অনুমোদিত হয় না, যা সাধারণ ব্যবহারের ক্ষেত্রে)। আপনার অবশ্যই উত্সটিকে অনুরোধকারীকে সেট করতে হবে (কীভাবে নীচে ম্যাট বুসির উত্তর দেখুন)।
অরকমান

98

উপরের সমস্ত উত্তর ভুল কারণ তারা অপশন প্রিফলাইট অনুরোধটি পরিচালনা করতে ব্যর্থ হয়েছে, সমাধানটি ম্যাক্স রাউটারের ইন্টারফেসটিকে ওভাররাইড করে। কৌনিক শিরোলেখ দিয়ে অ্যাঙ্গুলারজেএস $ http পাওয়ার অনুরোধটি ব্যর্থ হয়েছে দেখুন (সিওআরএসে আবদ্ধ)

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

19
"উপরের সমস্ত" ... উত্তরগুলি বিভিন্ন উপায়ে বাছাই করা যায় তাই এই বাক্যাংশটি আপনি কী চান তা বোঝায় না।
ডেভ সি

সাধারণ কর্স অনুরোধগুলির কোনও প্রিফলাইট নেই, এটি সমস্ত আপনি কী পরিবেশন করার চেষ্টা করছেন তার উপর নির্ভর করে।
লাইক

Access-Control-Allow-Credentials": "true"HttpOnly কুকিজ সহ অনুরোধগুলি ভুলে যাবেন না ।
ফেডেরিকো

23

উৎপত্তিস্থলের জন্য '*' ব্যবহার করবেন না, যতক্ষণ না আপনার সত্যিকারের সম্পূর্ণ জনসাধারণের ব্যবহারের প্রয়োজন হয়। উইকিপিডিয়া
যেমন বলেছে :

"" * এর মান এই ক্ষেত্রে বিশেষ যে এটি অনুরোধগুলিকে শংসাপত্র সরবরাহ করার অনুমতি দেয় না, যার অর্থ HTTP প্রমাণীকরণ, ক্লায়েন্ট সাইড এসএসএল শংসাপত্র, না এটি কুকিজ প্রেরণের অনুমতি দেয় না। "

তার অর্থ, আপনি প্রচুর ত্রুটি পাবেন, বিশেষত ক্রোমে যখন আপনি উদাহরণস্বরূপ একটি সাধারণ প্রমাণীকরণ প্রয়োগ করার চেষ্টা করবেন।

এখানে একটি সংশোধন করা আবরণ রয়েছে:

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

এবং এই সমস্ত শিরোনামকে প্রিফলাইট বিকল্পগুলির অনুরোধের জবাব দিতে ভুলবেন না।


1
আমি এই র‍্যাপারটির ব্যবহারটি বেশ বুঝতে পারি না, আপনি কীভাবে এই কোডটি দিয়ে আপনার http হ্যান্ডেলটি গুটিয়ে রাখবেন তার একটি উদাহরণ দিতে পারেন? আমি গরিলা ম্যাক্সটি ব্যবহার করছি তাই আমার বর্তমান ব্যবহারটি হ'ল router.HandleFunc("/user/action", user.UserAction) http.Handle("/", router) http.ListenAndServe(":8080", nil).Set("Access-Control-Allow-Origin", "*")
ম্যাট বুচি

2
আমি এখন অ্যাডডিফল্টহাইডারদের সাথে আমার হ্যান্ডেল কলগুলি মোড়ানো করছি router.HandleFunc("/user/action", addDefaultHeaders(user.UserAction)) যদিও আমার প্রায় 16 টি রুট রয়েছে এটি আদর্শ নয় তবে HTTP প্যাকেজ বা ম্যাক্স রাউটার স্তরটিতে মোড়ক হিসাবে নির্দিষ্ট করার কোনও উপায় নেই
ম্যাট বুচি

14

একটি উপযুক্ত গোলং মিডলওয়্যার সেট করুন, যাতে আপনি যে কোনও শেষ পয়েন্টে পুনরায় ব্যবহার করতে পারেন।

সহায়তার ধরণ এবং ফাংশন

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

শেষপ্রান্ত

রাখবেন! মিডলওয়্যারগুলি বিপরীত আদেশে প্রয়োগ করা হয় (এক্সপেক্টজিইটি () প্রথমে আগুন লাগে)

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

14

আপনি যদি নিজের রাউটারটিকে ওভাররাইড করতে না চান (যদি আপনার অ্যাপটি এটি সমর্থন করে এমন কোনও উপায়ে কনফিগার না করে বা রুটের ভিত্তিতে কোনও রুটে CORS কনফিগার করতে চান) তবে পূর্বের ফ্লাইটের অনুরোধটি পরিচালনা করতে একটি অপশন হ্যান্ডলার যুক্ত করুন ।

যেমন, গরিলা মুক্সের সাথে আপনার রুটগুলি দেখতে দেখতে এমন হবে:

accounts := router.Path("/accounts").Subrouter()
accounts.Methods("POST").Handler(AccountsCreate)
accounts.Methods("OPTIONS").Handler(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 কীভাবে কাজ করে তা বোঝার পাশাপাশি) এটি একটি প্রাকফ্লাইট অনুরোধের এইচটিটিপি পদ্ধতি প্রকৃত অনুরোধের এইচটিটিপি পদ্ধতি থেকে পৃথক। সিওআরএস শুরু করার জন্য, ব্রাউজারটি এইচটিটিপি পদ্ধতি বিকল্পগুলির সাথে একটি প্রিফ্লাইট অনুরোধ প্রেরণ করে, যা আপনাকে আপনার রাউটারে স্পষ্টভাবে পরিচালনা করতে হবে, এবং তারপরে, যদি এটি যথাযথ প্রতিক্রিয়া পায় if"Access-Control-Allow-Origin": origin আপনার অ্যাপ্লিকেশন থেকে (বা "*") প্রকৃত সূচনা করে অনুরোধ।

আমি আরও বিশ্বাস করি যে আপনি কেবল স্ট্যান্ডার্ড ধরণের অনুরোধের জন্য "*" করতে পারেন (যেমন: জিইটি), তবে অন্যদের জন্য আপনাকে আমার উপরের মতো স্পষ্টতই মূলটি সেট করতে হবে।


12

আমি এই মামলার জন্য মোড়ক তৈরি করি:

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

উপরে বর্ণিত সমাধানগুলি সঠিক হিসাবে আমার উপরে বর্ণিত একই সমস্যাটি ছিল, আমার সেট আপটি নিম্নরূপ: 1) ক্লায়েন্টের অ্যাংুলারজ 2) জিও সার্ভারের জন্য বিগো ফ্রেমওয়ার্ক

দয়া করে এই পয়েন্টগুলি অনুসরণ করুন 1) সিওআরএস সেটিংসগুলি কেবলমাত্র জিও সার্ভারে সক্ষম করা আবশ্যক 2) এটি ছাড়া কৌণিক জেজে কোনও ধরণের শিরোনাম যুক্ত করবেন না

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

আপনার সার্ভারে অনুরোধটি প্রক্রিয়া শুরু হওয়ার আগে সিওআরএস সেটিংস যুক্ত করুন যাতে প্রিফলাইট অনুরোধটি 200 টি ঠিক আছে যার পরে অপশন পদ্ধতিটি জিইটি, পোস্ট, পুট বা আপনার অনুরোধের ধরণে রূপান্তরিত হবে।


-7

আমি জানি এটি উত্তরের একটি ভিন্ন টুইস্ট, কিন্তু এটি কি ওয়েব সার্ভারের জন্য উদ্বেগের বিষয় নয়? উদাহরণস্বরূপ, nginx , সাহায্য করতে পারে।

ngx_http_headers_module মডিউল পারবেন, "মেয়াদ শেষ" এবং "ক্যাশে-নিয়ন্ত্রণ" হেডারের ক্ষেত্র, এবং অবাধ ক্ষেত্র যোগ করার সময় একটি প্রতিক্রিয়া শীর্ষক করতে

...

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

উত্পাদনে আপনার যেতে পরিষেবাটির সামনে nginx যুক্ত করা বুদ্ধিমান বলে মনে হচ্ছে। অনুরোধ অনুমোদন, লগিং এবং সংশোধন করার জন্য এটি আরও অনেক বৈশিষ্ট্য সরবরাহ করে। এছাড়াও, এটি আপনার পরিষেবাতে কাদের অ্যাক্সেস রয়েছে তা নিয়ন্ত্রণ করার ক্ষমতা দেয় এবং কেবল এটিই নয় তবে একজন আপনার অ্যাপে নির্দিষ্ট অবস্থানগুলির জন্য বিভিন্ন আচরণ নির্দিষ্ট করতে পারে, যেমন উপরে বর্ণিত demonst

আমি কেন আপনার এপিআই দিয়ে একটি ওয়েব সার্ভার ব্যবহার করব সে সম্পর্কে আমি যেতে পারি, তবে আমি মনে করি এটি অন্য আলোচনার জন্য একটি বিষয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.