【问题标题】:Cannot embed EJS when piping a response管道响应时无法嵌入 EJS
【发布时间】:2016-01-24 11:04:27
【问题描述】:

所以我想我pipe 一个html 文件作为响应,而不是res.render 以获得更快的性能。

代替

res.render('form',{title:'Login',userField:'Username',passField:'Password',photo: photo});

我愿意

var path  = 'views/form.ejs';
var stream = fs.createReadStream(path);
stream.pipe(res);

form.ejs 我有这个<% include menu %> 在用pipe 响应时不起作用。在我的浏览器中,我看到了<% include menu %>

我应该如何解决这个问题?还是因为管道将html文件逐个发送,所以无法正确渲染和嵌入,所以没有解决方案?

谢谢

【问题讨论】:

    标签: node.js express stream response


    【解决方案1】:

    stream.pipe() 方法完全不知道您的任何渲染需求。

    res.render() 旨在期望一个可渲染的模板和一个配置的视图引擎。您可以在 express 的源代码中看到这一点:

    res.render 调用app.render,后者调用view.render

    当您将结果传递给stream.pipe 时,绝对没有任何东西会尝试以res.render 的方式呈现属性。

    您也可能不会仅仅通过使用管道获得任何“性能”。

    简而言之:你想渲染你的结果,所以使用res.render()

    【讨论】:

    • 一个很好的观点。我不认为管道是模板和视图不可知的。 Render 旨在处理诸如模板和 EJS 之类的事情。我猜管道最适合用于 JSON 和数据文件。谢谢。
    【解决方案2】:

    只是为了添加到上面的答案......如果需要管道以获得特定的视图。 就像邓肯霍尔说的那样,使用'.ejs'你的模板引擎是让你的“ejs标记”工作的唯一方法,通过调用res.render('view')。另外,正如您可能在代码中指定的那样,您的视图文件夹将用于 ejs,它将尝试挂钩该文件夹中的所有视图,因此您不能将同一文件夹用于 html 文件,否则它将崩溃:

    Error: Failed to lookup view "clubs" in views directory "...
    

    因此,如果您仅将 html 与 css 以及一些 JS 和图片一起用于纯静态页面,您可以创建一个特殊的 html 文件夹来存放您的 html 文件。 然后使用:

    app.get('/', function(req, res) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        var clubs = fs.createReadStream(__dirname + '/html/clubs.html')
        clubs.pipe(res);
    });
    

    例如,是的,如果该路由被大量访问,它将提高 IO 性能,因为块将以触发快乐的方式被枪杀! 毕竟,非阻塞 IO、流、长轮询和异步是 Node 高效的原因。 干杯~

    【讨论】:

      【解决方案3】:

      直接从fs加载模板不是一个好主意,也许你可以在监听之前将它加载到内存中。例如:

      const viewFoo = fs.readFileSync('./views/foo.html');
      const templateFoo = ejs.compile(viewFoo);
      
      // then in your handler:
      res.end(templateFoo({ title:'Login' /* ... */ }));
      

      如果你想使用流作为数据在ejs模板中渲染, 你可以试试ejs-stream2。 例如:

      const { compile } = require('ejs-stream2');
      
      const template = compile('<div><%- contentStream %-></div>');
      
      app.get('/', (req, res) => {
        const stream = template({ contentStream: renderToNodeStream(<App/>);
        stream.pipe(res);
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-01
        • 2019-10-10
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 2014-09-21
        • 2017-04-05
        • 2019-07-25
        相关资源
        最近更新 更多