clojurepedestal

No 'Access-Control-Allow-Origin' header is present when origin is allowed in Pedestal


When I try and request a resource from a cljs app (running on http://localhost:3000) to my Pedestal server (running on http://localhost:8080) I get the below error. I would like to allow CORS from http://localhost:3000:

XMLHttpRequest cannot load http://localhost:8080/db/query. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

I am using cljs-http to send the request from the client. The request looks something like this:

(defn load-server-data
  []
  (go
    (let [q (<! (http/post "http://localhost:8080/db/query"
                           {:edn-params {:query '[:find ?rep ?last
                                                  :where
                                                  [?rep :sales-rep/first-name ?last]]}}))]
      (println "q" q))))

The route for /db/query looks like this:

(defroutes routes
           [[["/db"
              {:post handlers/db-post}
              ["/query" {:post handlers/db-query}
               ^:interceptors [interceptors/edn-interceptor]]]]])

This is the handler for /db/query:

(defn db-query
  [req]
  (let [edn-params (:edn-params req)
        q (:query edn-params)
        args (:args edn-params)
        q-result (apply d/q q (d/db conn) args)]
    {:status 200
     :body   (pr-str q-result)}))

To run the server I execute this function in the REPL.

(defn run-dev
  "The entry-point for 'lein run-dev'"
  [& args]
  (println "\nCreating your [DEV] server...")
  (-> service/service
      (merge {:env                     :dev
              ::server/join?           false
              ::server/routes          #(deref #'service/routes)
              ::server/allowed-origins {:creds true :allowed-origins (constantly true)}})
      server/default-interceptors
      server/dev-interceptors
      server/create-server
      server/start))

There does not seem to be much information around CORS for Pedestal. I have looked at the cors example but it seems to just work while mine does not. Is there another interceptor I need to add to my routes or some sort of configuration setting that I am missing here?


Solution

  • I have figured out the problem. It turns out that an error was being thrown, however, it was getting swallowed and hidden from my debugger. Simply adding a try catch around my handler function fixes the problem.

    (defn db-query
      [req]
      (try
        (let [edn-params (:edn-params req)
              q (:query edn-params)
              args (:args edn-params)
              q-result (apply d/q q (d/db conn) args)]
          {:status 200
           :body   (pr-str q-result)})
        (catch Exception ex
          {:status 400
           :body   "Not authorized"})))