【问题标题】:how can I render an HTML page with express and at the same time pass json data to that HTML?如何使用 express 呈现 HTML 页面,同时将 json 数据传递给该 HTML?
【发布时间】:2018-05-24 15:33:45
【问题描述】:

如何使用 express 呈现 HTML 页面,同时将 json 数据传递给该 HTML?我从 mongoDB 数据库的集合中获取 json 数据。 我的 /solutions 路由器文件如下所示:

router.get('/', function (req, res, next) {
  db.solutions.find(function (err, docs) {
    res.send(docs);
  });
});

在 AngularJS 控制器中:

$http.get('/solutions').then(function(res) {
  console.log(res);
});

我没有在解决方案文件中指定 /solutions,因为我是在我的主 server.js 文件中指定的。

我知道这只会以 json 格式发送数据。如何将 json 传递给 HTML 并同时显示?

我从 mongoDB 得到的集合只有一个字段(不包括 id)。

【问题讨论】:

    标签: angularjs json mongodb express


    【解决方案1】:

    这是实现此目的的示例项目

    考虑以下项目结构

    www/          
      questions.html  // questions angular template
      solutions.html  // solutions angular template
      script.js       // angular code
    app.js            // main entry point
    api.js            // the api endpoint
    db-mock.js        // a mongo db mock for demo purpose
    package.json      // app dependencies
    

    package.json

    使用以下命令初始化项目依赖

    $ npm init
    $ npm install --save express serve-static
    

    api.js

    var express = require('express');
    var router = express.Router();
    var db = require('./db-mock');
    
    router.get('/questions', function(req, res) {
        var questions = db.questions.find();
        res.setHeader('Content-Type', 'application/json');
        res.send(JSON.stringify(questions));
    });
    
    router.get('/solutions', function(req, res) {
        var solutions = db.solutions.find();
        res.setHeader('Content-Type', 'application/json');
        res.send(JSON.stringify(solutions));
    });
    
    module.exports = router;
    

    app.js

    这是我们的主要入口点。这里声明了 Express 服务器和路由。

    var express = require('express');
    var serveStatic = require('serve-static');
    var api = require('./api');
    var app = express();
    var port = process.env.PORT || 8080;
    
    // Serve API
    app.use('/api', api);
    
    // Serve static files (our client-side code)
    app.use(serveStatic('www'));
    
    // Start server
    app.listen(port, function() {
        console.log('Server listening on port %d', port);
    });
    

    db-mock.js

    由于我们不需要真正的 Mongo 服务器来制作示例,所以我们只是模拟它。

    // Mock Mongo db
    var db = {
        questions: {
            find: function() {
                return [
                    {id: 1, name: "Why ?"},
                    {id: 2, name: "How do I do this ?"},
                    {id: 3, name: "What's up ?"},
                    {id: 4, name: "Siri, tell me a joke"},
                    {id: 5, name: "Are we alone ?"}
                ]
            }
        },
        solutions: {
            find: function() {
                return [
                    {id: 1, name: "Triswarm"},
                    {id: 2, name: "U-bam"},
                    {id: 3, name: "Betacore"},
                    {id: 4, name: "Qvotrax"},
                    {id: 5, name: "Homezuning"}
                ]
            }
        }
    }
    
    module.exports = db;
    

    script.js

    AngularJS 模块和控制器声明

    angular.module('app', []);
    
    angular
        .module('app')
        .controller('SolutionsController', ['$scope', '$http', function ($scope, $http) {
            $http.get('/api/solutions')
                 .then(function(res) {
                     $scope.solutions = res.data;
                 });
        }])
        .controller('QuestionsController', ['$scope', '$http', function ($scope, $http) {
            $http.get('/api/questions')
                 .then(function(res) {
                     $scope.questions = res.data;
                 });
        }]);
    

    questions.html

    问题客户端模板

    <!doctype html>
    <html lang="en" ng-app="app">
    <head>
      <meta charset="utf-8">
      <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.min.js"></script>
      <script src="script.js"></script>
    </head>
    <body ng-controller="QuestionsController">
      <h1>Questions</h1>
      <ul>
        <li ng-repeat="question in questions">{{question.name}}</li>
      </ul>
    </body>
    </html>
    

    solutions.html

    解决方案客户端模板

    <!doctype html>
    <html lang="en" ng-app="app">
    <head>
      <meta charset="utf-8">
      <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.min.js"></script>
      <script src="script.js"></script>
    </head>
    <body ng-controller="SolutionsController">
      <h1>Solutions</h1>
      <ul>
        <li ng-repeat="solution in solutions">{{solution.name}}</li>
      </ul>
    </body>
    </html>
    

    启动

    $ node app 
    

    打开浏览器http://localhost:8080/questions.html,您应该会看到 5 个问题

    打开浏览器http://localhost:8080/solutions.html,您应该会看到 5 个解决方案

    替代解决方案

    您可以使用模板引擎在服务器端呈现 HTML,例如 ejs。你可能甚至不再需要 angular。

    $npm install ejs --save
    

    在项目根目录下添加一个views 目录,您将在其中放置服务器端模板

    views/
      solutions.ejs
    

    solutions.ejs

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title><%= pageTitle %></title>
    </head>
    <body>
        <h1><%= pageTitle %></h1>
        <ul><% for(var i=0; i<solutions.length; i++) { %>
            <li><%= solutions[i].name %></li>
        <% } %></ul>
    </body>
    </html>
    

    以这种方式更改app.js

    // Declare /solutions route
    app.get('/solutions', function(req, res) {
        var solutions = db.solutions.find();
        // Use `solutions.ejs` template to render
        res.render('solutions.ejs', {pageTitle: "Solutions", solutions: solutions});
    });
    

    现在用node app 启动你的服务器并浏览到http://localhost:8080/solutions

    /questions等其他路由执行相同操作

    这是一个非常简单的示例,请阅读 ejs 文档以符合您的需求: https://github.com/mde/ejs

    【讨论】:

    • 这在只有一条路线时有效。在我的应用程序中,我有:var appRoutes = require('./backend/routes/api');var solutions = require('./backend/routes/solutions');var questions = require('./backend/routes/questions');当我尝试在 /solutions 或 /questions 路由上呈现 HTML 时,不使用 res.render,而是使用 res.send 我只获取原始 json 格式的数据
    • 我试图理解.. 您想将后端 (node+express) 用作 API 服务器或 API 服务器加 HTML 渲染器? (然后,html 模板将由服务器端模板引擎处理)
    • 就像一个 API 服务器。我有不同文件中的所有路由,并且我有多个 HTML 文件。我尝试了您的解决方案,当我只有一个 HTML 文件(index.html)但如果我想在使用路由器的另一个文件中使用您的解决方案(app.js 文件)时它可以工作:var router = express.Router();,我使用另一个 HTML 文件(不是 index.html),我只得到 json 格式的数据。
    • 我已经更新了我的答案,/api 路由现在在一个专用的api.js 文件中声明,您可以调用/questions.html/solutions.html 模板来调用不同的api 路由。请注意,这只是一个简单的示例。如果您想在客户端使用 Angular,您可以考虑使用客户端路由器来处理 /api 以外的路由
    • @blooddrunk 回答了你的问题吗?
    猜你喜欢
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2020-01-29
    相关资源
    最近更新 更多