如何在将JavaScript代码发送给用户之前在Node.js中执行该代码?

3
我正在使用Ghost平台运营博客。Ghost是基于Nodejs构建的,但我对它不太了解。我已经编写了以下代码,用于获取每篇文章的第一张图片并将其设置为og:image。问题在于它只有在网站到达用户机器后才会加载。是否可能从服务器执行此操作,然后将其发送给用户?
    $(document).ready(function() {
        var siteURL = location.host;

         if(
                $('.post-template').length > 0 || 
                $('.page-template').length > 0
            ) {

                var featured_image = $('.post-content img[alt="featured-image"]').first().attr('src');


                // check if the featured image exists
                if(featured_image && featured_image.length > 0) {
                    var featured_image_fe = featured_image;
                    // create container for the image
                    if(featured_image_fe.substr(0,7) != 'http://'){
                        featured_image_fe = siteURL + featured_image_fe;
                    }

                    $('meta[property="og:image"]').attr('content', featured_image_fe);
                } else {
                    var featured_image = $('.post-content img').first().attr('src');

                    if(featured_image && featured_image.length > 0) {

                        var featured_image_nfe = featured_image;
                        if((featured_image_nfe.substr(0,7) != 'http://') && (featured_image_nfe.substr(0,8) != 'https://')){
                            featured_image_nfe = 'http://' + siteURL + featured_image_nfe;
                        }

                        $('meta[property="og:image"]').attr('content', featured_image_nfe);
                    } else {
                        $('meta[property="og:image"]').attr('content', 'http://media.techhamlet.com/wp-content/uploads/2014/06/techhamlet.jpg');
                    }


                }
            }
    }

Node.js使用JavaScript语言并在服务器端运行。您拥有的代码是JavaScript,但是是客户端应用程序。服务器通过网络与客户端通信。在您的情况下,它们都使用JavaScript,但它们是不同的。请参阅:http://en.wikipedia.org/wiki/Client%E2%80%93server_model - Yves M.
2个回答

6

是的,这绝对是可能的。我已经想出了一个快速的方法来使得Ghost支持og:image。这绝对不是最优解决方案,但它需要最少的代码更改。你需要安装cheerio并修改两个文件。

core/server/controllers/frontend.js

我们需要更新formatResponse函数,在第76行开始。

var cheerio = require('cheerio');

function formatResponse(post) {
    var $ = cheerio.load(post.html);
    var firstImage = $('img').first();
    if(firstImage) {
        post.meta_image = firstImage.attr('src');
    }

    // Delete email from author for frontend output
    // TODO: do this on API level if no context is available
    if (post.author) {
        delete post.author.email;
    }
    return {post: post};
}

我们正在通过cheerio运行post HTML。获取第一张图片,并将src填充到帖子对象的新变量(meta_image)中。这将使该变量在handlebars模板系统中可用。

content/themes//default.hbs

在这里,我只是更新了{{!页面元数据}}部分,如下所示:

    {{! Page Meta }}
    <title>{{meta_title}}</title>
    <meta name="description" content="{{meta_description}}" />
{{#if this.post.meta_image}}
    <meta property="og:image" content="{{this.post.meta_image}}" />
{{/if}}
    <meta name="HandheldFriendly" content="True" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

我们只是检查是否存在this.post.meta_image,如果存在就创建meta标签。

更好的解决方案

为了添加这个功能,你真正需要做的是向帖子对象添加一个额外的字段来存储og:image。然后你可以从管理界面中填充该字段,或者在保存帖子时解析HTML并将值放入适当的字段中。这样,填充og:image的逻辑仅在保存页面时运行一次,而不是每次显示页面时都要运行。


1

这本来是一条评论,但是太长了,而且我也不认识 Gosht

你为什么要这样做?

if (
    $('.post-template').length > 0 || 
    $('.page-template').length > 0
)

如果有重复的条件检查,只会让程序变慢。

如果我理解你的目标正确的话,你需要动态加载图片,如果node.js可以访问图像列表,你可以使用视图(express或jade)动态生成HTML,使用正确的HTML字段而不是JavaScript。

你可以做以下操作:

在node.js中:

var express = require('express'),
    app = express();

function execute () {
    return 'Html stuff to load the image';
}

app.get('/', function (res, req) {
    var html_begin = '<head></head><body>',
        html_end = '</body>';

    res.send(html_begin + execute() + html_end);
});

所以客户端收到了。
<head>
</head>
<body>
    Html stuff to load the image
</body>

但是你不能只是告诉node.js在发送页面之前执行某些操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接