Curiosity
Curiosity

Reputation: 671

How to enable cross-origin requests in compojure?

I've been trying a lot of methods to implement this and I thought that the correct way is to set such headers (I did so in a nodejs/express app):

"Access-Control-Allow-Origin"  "*"
"Access-Control-Allow-Methods" "GET,PUT,POST,DELETE,OPTIONS"
"Access-Control-Allow-Headers" "X-Requested-With,Content-Type,Cache-Control"

I have written such function:

(defn allow-cross-origin
  "middleware function to allow cross origin"
  [handler]
  (fn [request]
    (let [response (handler request)]
      (do
        (assoc-in response [:headers "Access-Control-Allow-Origin"]  "*")
        (assoc-in response [:headers "Access-Control-Allow-Methods"] "GET,PUT,POST,DELETE,OPTIONS")
        (assoc-in response [:headers "Access-Control-Allow-Headers"] "X-Requested-With,Content-Type,Cache-Control")))))

(def handler (-> app wrap-params allow-cross-origin))

I've tested it with curl -v and found that only the last value realy exists in a response. All I need is to write multiple key-value pairs in headers. How to do it? Or maybe there is another way to solve the problem.

Upvotes: 4

Views: 1815

Answers (1)

schaueho
schaueho

Reputation: 3504

Remember that assoc-in still does not modify the original structure: response will always have the same value as per (handler request).

(let [response {}]
   (assoc-in response [:headers "Access-Control-Allow-Origin"]  "*")
   (assoc-in response [:headers "Access-Control-Allow-Methods"] "GET,PUT,POST,DELETE,OPTIONS")
   (assoc-in response [:headers "Access-Control-Allow-Headers"] "X-Requested-With,Content-Type,Cache-Control"))
==> {:headers {"Access-Control-Allow-Headers" "X-Requested-With,Content-Type,Cache-Control"}}

This is the effect you're seeing. To change this, you have to ensure that the result of the assoc-in calls get used again. The threading macro is useful for this:

(let [response {}]
 (-> response
     (assoc-in [:headers "Access-Control-Allow-Origin"]  "*")
     (assoc-in [:headers "Access-Control-Allow-Methods"] "GET,PUT,POST,DELETE,OPTIONS")
     (assoc-in [:headers "Access-Control-Allow-Headers"] "X-Requested-With,Content-Type,Cache-Control")))
 => {:headers {"Access-Control-Allow-Headers" "X-Requested-With,Content-Type,Cache-Control", "Access-Control-Allow-Methods" "GET,PUT,POST,DELETE,OPTIONS", "Access-Control-Allow-Origin" "*"}}

Upvotes: 3

Related Questions