1

我有一个提供 API 的简单 Node JS 应用程序。我可以node main.js让服务器运行并调用localhost:3000/api/names以成功获取名称列表。我想在此基础上使用 Reagent/Cljs。

我可以在localhost:3030. 我的问题是,如何从 Reagent 应用程序对 Node 应用程序进行 API 调用?还是我的架构全错了?我应该结合这两个应用程序吗?如果可以,如何结合?

我尝试将它们结合起来,但 Reagent 想要在 Ring 上运行,而 Node 应用程序想要在节点服务器上运行。所以我还是没有两个人交流。我尝试过阅读快速入门指南,但情况并不完全相同。我也尝试过这种方法,但无济于事。将这些部分组合在一起以便将 API 响应数据从 Node 应用程序带到 Reagent 应用程序的最简单方法是什么?或者有没有办法从我缺少的 Reagent 应用程序中调用 API 调用?

4

1 回答 1

1

是的,您需要在浏览器中运行的代码和服务器上运行的代码之间进行通信。

基本方法是使用 XHR。客户应该这样做:

(ns foo
  (:require [goog.net.XhrIo :as xhr]))

(xhr/send "/api/names"
          (fn [e]
            (prn (.. e -target getResponseText))))

或者有一个使用非常广泛的库cljs-http

 (ns foo
  (:require
    [cljs.core.async :refer [<!]]
    [cljs-http.client :as http])
  (:require-macros
    [cljs.core.async.macros :refer [go]]))

(go (let [response (<! (http/get "data.edn"))]
      (prn (:status response))
      (prn (:body response))))

它使用 core.async 通过通道将结果返回给您。但是,您实际上并不需要关心它来使用它,只是要注意go块中的事情将“稍后”发生。

对于高级用法,您可以使用 sente 创建websockets

网页的一个重要考虑因素是它们只能在为页面提供服务的同一端口上使用同一主机执行 XHR。因此,如果您将 API 托管在 localhost:3030,则必须从 localhost:3030 提供页面,以便您能够与之通信。(这称为同源策略)。

您在问题中声明您的 API 在端口 3000 上,而 Reagent 应用程序从 3030 提供服务。由于相同的来源政策,这将不起作用。有一个称为 CORS 跨域资源共享的标准,从技术上讲您可以使用它,但实际上不要这样做。而是从与 API 相同的服务器提供 HTML/Javascript。

这对您来说意味着您需要确保在构建 Reagent 应用程序时,包含最终 JavaScript 的 HTML 页面需要由为您的 API 提供服务的同一服务器提供服务。通常这是将 HTML 和 JavaScript 放入服务器上的资源文件夹的问题。

于 2016-02-06T20:28:25.890 回答