4

当我尝试从 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))

关于 Pedestal 的 CORS 似乎没有太多信息。我看过cors 的例子,但它似乎只是工作,而我的却没有。我是否需要将另一个拦截器添加到我的路由或我在这里缺少的某种配置设置中?

4

2 回答 2

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"})))
于 2015-10-28T05:46:49.317 回答
2

我原来的回复:

CORS 的目的是限制请求的来源。你必须有目的地告诉它请求来自哪里。这将解决它。

(def service {;other config stuff
              io.pedestal.http/allowed-origins ["http://localhost:3000"]}

看来这是一个重复的问题。显然,javascript ajax 请求根据定义仅限于单一来源。仅当生成http://localhost:3000的环服务器上的 clj-http 或 http-kit 发出 GET 请求,然后向同一个环服务器发出 cljs-http ajax 请求时,该代码才能在生产中工作端口 3000。我仍然不知道为什么你的 run-dev 不起作用,但如果你用 run 调用 lein,这肯定是正在发生的事情。

于 2015-10-23T06:25:55.670 回答