ExpressJS:将通配符路由和渲染与EJS

时间:2018-01-04 16:14:09

标签: javascript node.js angular express ejs

我正在开发一个Angular 4.x应用程序,它包含自己的内部路由。 它将在Express服务器上运行,不幸的是它有自己的路由覆盖Angular应用程序中的路由器。 我最初试图通过在Express服务器上使用通配符路由来解决这个问题,但它会导致其他问题。

部分内容还与使用EJS进行模板渲染有关。 我将逐步解释。

首先,我们有以下路线:

/ (root)
/appartment
/apartment/:id
/student
/student/:id

以下是呈现并返回的index.html文件:

<!doctype html>
<html lang="en">
  <head>
  </head>
  <body>

    <%- headerMenu %>

    <app-root></app-root>

    <%- footer %>
  </body>
</html>

由于Angular应用程序具有自己的内部路由,因此只会从服务器返回index.html文件,并且应该为所有路径返回该文件。

如您所见,有一些EJS模板标签。 我们的真实应用程序是更大的网站的一部分,因此对于这个特定的应用程序,我们使用EJS注入在我们所有页面上找到的相同headerMenu和页脚内容。 多年来,各种网页/应用程序都是使用不同的框架制作的,而且这个框架使用的是Angular 4.x,托管在Express服务器上。

以下是我们的js文件的工作版本:

var path = require("path");
var express = require("express");
var ejs = require("ejs");
var bodyParser = require("body-parser");
var http = require('http');

//....... All other content here .... 
//....... All other content here .... 
//....... All other content here .... 

var app = express();
app.set('view engine', 'html');
app.engine('html', ejs.renderFile);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.get(['/', '/apartment(/:id)?', '/student(/:id)?'], function(req, res) {
    res.render('../dist/index.html', {
        headerMenu: ourWebContent.headerMenu,
        footer: ourWebContent.foooter
    });
});

app.use(express.static(path.join(__dirname, '/dist')));

app.listen(env.port, function () {
    console.log('server running at ' + env.port + ', go refresh and see magic');
});

在此代码部分之前定义了属性env.port和ourWebContent。

如您所见,Angular应用程序中使用的每个路径也在Express服务器代码中明确说明:

['/', '/apartment(/:id)?', '/student(/:id)?']

不幸的是,通过这种方法,对于我在Angular应用程序中引入的每个新路由,我也必须在Express中添加它们。

我尝试过通配符路由,如下所示:

['/', '/*']

它应该有效,但在我的应用程序中它会导致以下错误:

Uncaught SyntaxError: Unexpected token <

现在,你们中的一些人可能已经注意到以下代码在下面路线:

app.use(express.static(path.join(__dirname, '/dist')));

这是存储编译的index.html的地方。 在谷歌搜索错误之后,虽然我不记得我在哪里找到了解决方案(在Stackoverflow上的其他地方)以及背后的确切解释,但如果我在路由之前移动此特定代码行,它似乎正在工作。

不幸的是,它引入了一个新问题:EJS大部分时间都不会渲染。 我最终看到的是未呈现的文本,而不是headerMenu和页脚。

所以问题是:如何在不破坏EJS渲染的情况下修复通配符路由?

2 个答案:

答案 0 :(得分:0)

为避免此类冲突,您应该做的(至少我做的)是为您的快速API添加前缀。 因此,当您向/提出请求时,您的快递应用程序将返回index.ejs(或任何扩展名)

router.get('/', function(req, res, next) {
  res.render('index');
});

现在,如果您有appartments的API,那么它就是这样:

app.use('/api/appartments', require('routes/appartments'));

//inside routes/appartments.js
router.get('/', function(req, res, next) {
  return res.send([//apartments])
});

router.get('/:id', function(req, res, next) {
  return res.send({//apartment})
});

以及学生或其他什么。

这样,当API在/ api /...运行时,Angular可以自由使用它自己的路径。

答案 1 :(得分:0)

您可以从角度动态设置路线,这是一个示例:

创建路线处理程序:

var handler = function (req, res) {
    res.render('view');
}

通过调用/addRouteDynamically/path动态添加路由:

app.get('/addRouteDynamically/:path', function (req, res, next) {

     var path = req.params.path;

     app.get(path , handler);

});

现在,如果你打电话给例如GET /addRouteDynamically/appartement%2F%3Aid,快递将定义由handler方法处理的新路线

请注意appartement%2F%3Aid相当于appartement/:id