当我尝试从cljs应用程序(在http://localhost:3000上运行)请求资源到我的Pedestal服务器(在http://localhost:8080上运行)时,我得到以下错误。我想允许来自http://localhost:3000的CORS:
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.
我正在使用cljs-http从客户端发送请求。请求看起来像这样:
(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))))
/db/query
的路线如下:
(defroutes routes
[[["/db"
{:post handlers/db-post}
["/query" {:post handlers/db-query}
^:interceptors [interceptors/edn-interceptor]]]]])
这是/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)}))
要运行服务器,我在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))
基座的CORS似乎没有太多信息。我看过cors example,但它似乎只是工作而我的没有。是否有我需要添加到我的路由的拦截器或我在这里缺少的某种配置设置?
答案 0 :(得分:3)
我已经找到了问题所在。事实证明,错误被抛出,然而,它被调试器吞没并隐藏起来。只需在我的处理函数中添加一个try catch就可以解决问题。
(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"})))
答案 1 :(得分:1)
我最初的回应:
CORS的目的是限制请求的来源。你有 故意告诉它请求的来源。这将解决它。
(def service {;other config stuff io.pedestal.http/allowed-origins ["http://localhost:3000"]}
看来这是重复question。显然,javascript ajax请求的定义仅限于单一来源。只有当生成http://localhost:3000的环形服务器上的clj-http或http-kit发出GET请求,然后在端口3000上对同一个环服务器发出cljs-http ajax请求时,该代码才能在生产中工作我仍然不知道为什么你的run-dev不起作用,但是如果你用奔跑打电话给lein,这肯定是正在发生的事情。