node.js和单页Web应用程序

时间:2013-09-26 23:06:56

标签: javascript ajax json node.js express

我正在查看后端的express.js和客户端的JS。 我的应用程序是单页Web App。

服务器只提供JSON消息,我的问题是关于express的“路由”。 是否应该使用路由来连接UI和服务器端业务逻辑? 如何使用我的单页应用程序?

所以假设,客户端向服务器发出Ajax调用,在数据库中查找值,并且有服务器端脚本将JSON提供回UI。如何设置此UI和节点脚本关系?

有人可以对此有所了解吗?

2 个答案:

答案 0 :(得分:38)

单页应用程序是存在于单个HTML文档中的应用程序。这意味着如果要向用户显示一些不同的内容,根据应用程序的状态,您需要进行一些DOM操作(使用不同的HTML删除和替换当前文档的某些元素)以便更新的观点'用户看到的。对不起,如果这对你来说很明显,请不要冒犯。我想我从这里开始。和我一起,我将解释你的路由情况将如何发挥作用(或多或少)。

URL由几个不同的部分组成,每个部分向浏览器通知为了下载用户试图访问的资源所需的特定信息位。通常情况下,您正在寻找的资源在某个地方的服务器上关闭,并且浏览器知道这一点,因为URL中的部分类似于协议' (' http:')和'主持人' (' www.mydomain.com'),因此它会转到该服务器以查找您要求的内容。还有'查询' URL中的参数,其向服务器提供关于特定动作的一些附加信息,例如搜索查询的搜索项。在查询参数之后,出现了' hash'。哈希就是单页应用程序发生魔力的地方......呃,好吧,有点......

首先关于哈希。当你添加一个'#'然后,浏览器将URL后面的信息解释为当前显示的文档中的某个位置(元素)。这意味着,如果你有一个带有' id' '主要'并添加' #main'在URL的末尾,如下所示:' http://www.example.com#main' ;,浏览器将滚动' (通常是跳#39;)到该元素的开头,以便您可以看到它。但请注意,如果您输入' http://www.example.com/#main' (通过斜杠将URL与URL分开)然后您将强制重新加载完整页面,浏览器将尝试按名称“#main'”查找文件。在服务器上(我打赌它没有找到它)。

这里要说的是,如果网址中存在哈希值,浏览器将不会尝试离开当前文档,当然上面提到例外情况,这很好因为单页应用不想离开页面或从服务器请求新文档。 (了解单页应用的路由方式有何不同?)

现在,关于哈希的整个事情对单页应用程序来说并不重要,因为你可以在不处理所有内容的情况下制作一个。一堆点击处理程序和DOM操作是您真正需要的......但是,这意味着用户将无法共享指向您应用中特定视图的链接。 URL永远不会改变,我们永远无法直接导航到任何特定视图。我们总是从您的应用的起始位置开始,这可能很容易成为一个非常烦人的情况。

如果您的单页应用程序具有不同的视图,并且您希望用户能够通过书签或链接直接导航到特定的视图,那么您需要在前端实现一种路由形式除了您需要在后端实现的路由(数据API的路由等),这意味着您将需要使用哈希。

我不想了解不同的框架如何在前端完成路由,但这基本上是在用户点击链接时更新浏览器的地址字段,并观察地址栏以确定当前URL是什么,并将与该URL关联的HTML加载到文档树中指定位置的DOM中。

因此,在单页应用程序中,您在服务器上有一条处理呈现应用程序HTML文档(index.html)的路径,并且您有负责处理应用程序数据的路由(创建数据库中的新实例,登录和注销,编辑或销毁数据库中的实例,以及获取通过AJAX请求调用的数据...。

这实际上是一个相当复杂的情况,因为HTML5允许我们能够放弃哈希(借助于服务器上的某些链接重写)并且还能够使用'返回'并且'转发'按钮好像我们实际上已经远离原始文档(我们还没有,因为我们只将浏览器指向完全相同的URL,只有修改后的哈希值,因此没有发生新的页面加载) 。传统的网站导航和链接可以通过利用浏览器的历史API来实现,该API可以从版本10开始用于IE(我相信),其他大型浏览器供应商已经提前了,因此,利用此技术的框架将允许您的用户在不使用URL中的哈希值的情况下导航您的应用。解释这是一个转移,并不是理解单页应用程序中的路由所必需的,但它很有趣,你最终还是必须学习它,可能..

AJAX应该用于从服务器请求JSON。 AJAX请求总是会命中你的服务器,因为你没有在AJAX请求中包含哈希符号(这样做会很荒谬,因为哈希仅用于文档内浏览),因此服务器端路由必须负责用于公开您的数据API(考虑一个RESTful)。虽然这不是他们在单页应用程序中的唯一目的,但它可能是最重要的一个。

Soooo,要把它包起来,你将有两套路线。一个在客户端上(作为客户端框架的一部分,如AngularJS或EmberJS,列表继续......我更喜欢Angular,但是对于那个有一个相当陡峭的学习曲线。),并且在服务器上有一个。当您考虑“服务器路由”时。想想数据API。当您想到“页面路由”时,请记住这一切都是在客户端上通过您使用初始服务器响应提供的javascript来处理的(这是渲染所涉及的唯一必需的服务器端路由) HTML到浏览器,加载' index.html'以及所有必要的脚本和样式表等)。您将使用express.static中间件来提供静态文件,因此您不必担心为这些内容分配路由。

编辑快速提及AJAX实现。 在服务器上,您将拥有类似于Alex提供的路由作为示例,您将使用您选择的框架或库公开的任何XMLHttpRequest(XHR)对象从客户端调用这些URL。现在,对于框架/库来说,将这些请求实现为Promises http://wiki.commonjs.org/wiki/Promises/A或多或少是标准和最佳实践。你应该自己阅读一下它,但我可以通过说它是一个类似于' try,catch,throw'的异步操作来总结它。在同步操作中。您将实例化一个promise对象,通过它您将尝试从服务器加载数据,例如,通过GET请求。确保您已分配函数来处理对您发出请求的URL(服务器端路由)发出的请求!您实例化并随后通过服务器向服务器发出请求的此对象承诺一旦从服务器返回请求将结果返回给您(无论是否成功)如果成功,它将调用您编写的函数,将为其提供服务器中的数据。如果失败,它将调用另一个也由您编写的函数,并将为其提供错误对象(或“失败原因”),以便您可以适当地处理错误。

希望这有助于回答你的问题。

答案 1 :(得分:1)

您只需动态路由您提供的请求。您的HTML,CSS,JS都是静态资产。因此,处理路由所需的只是您的数据。

听起来你想要一个 Restful API ,这基本上意味着你拥有特定资源的URL,以及用于操作它们的HTTP动词。

类似的东西:

  • GET /books.json - 获取所有图书
  • POST /books.json - 创建一个新书,其中包含在请求正文中传递的属性
  • GET /books/123.json - 获取ID为123的图书
  • PUT /books/123.json - 使用在请求正文中传递的属性更新现有图书

This blog post seems to show how to set this up in Express.

一旦你有一个理智的API提供JSON,你只需让你的AJAX调用根据你想要获取的对象使用它。