对于我的生活,我找不到适用于我的 Angular 5 站点的服务器端渲染解决方案。在我最近的尝试中,我一直在关注 AngularFirebase.com提供的解决方案:https://angularfirebase.com/lessons/seo-angular-part-1-rendertron-meta-tags/
我的应用的所有内容都是硬编码的,所以我跳过了本教程的第一部分。我确实使用 Firestore 2 ,但仅用于捕获联系表单上的字段。我的路由非常简单,都包含在 module.ts 文件中。我所做的事情的内容包含在我的 index.js 文件中:
const functions = require('firebase-functions');
const express = require('express');
const fetch = require('node-fetch');
const url = require('url');
const app = express('');
const appUrl = 'customapp.firebaseapp.com';
const renderUrl = 'https://render-tron.appspot.com/render';
function generateUrl(request) {
return url.format({
protocol: request.protocol,
host: appUrl,
pathname: request.originalUrl
});
}
function detectBot(userAgent){
const bots = [
'bingbot',
'yandexbot',
'duckduckbot',
'slurp',
//Social
'twitterbot',
'facebookexternalhit',
'linkedinbot',
'embedly',
'pinterest',
'W3C_Validator'
]
const agent = userAgent.toLowerCase();
for (const bot of bots) {
if (agent.indexOf(bot) > -1) {
console.log('bot detected', bot, agent);
return true;
}
}
console.log('no bots found');
return false;
}
app.get('*', (req, res) =>{
const isBot = detectBot(req.headers['user-agent']);
if (isBot) {
const botUrl = generateUrl(req);
fetch(`${renderUrl}/${botUrl}`)
.then(res => res.text())
.then(body => {
res.set('Cache-Control', 'public, max-age=300, s-maxage=600');
res.set('Vary', 'User-Agent');
res.send(body.toString())
});
} else {
fetch(`https://${appUrl}/`)
.then(res => res.text())
.then(body => {
res.send(body.toString());
});
}
});
exports.app = functions.https.onRequest(app);
我已经使用这些重写设置了 firebase.json :
"rewrites": [
{
"source": "**",
"function": "app"
}
]
所有内容都成功部署,但是当我访问我的网站时,我的Firebase功能日志会吐出:
Function execution took 677 ms, finished with status: 'crash'
warning FetchError: request to https://test-297a3.firebaseapp.com/ failed, reason: getaddrinfo ENOTFOUND test-297a3.firebaseapp.com test-297a3.firebaseapp.com:443
at ClientRequest.<anonymous> (/user_code/node_modules/node-fetch/lib/index.js:1376:11)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at TLSSocket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at connectErrorNT (net.js:1025:8)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)
warning . Unhandled rejection
根据我的阅读here,似乎可能是我格式化网址的方式,但我尝试过以不同方式对其进行格式化。在第二个提取语句fetch(
https:// $ {appUrl} / )
我删除了&#34; https://&#34;,但提取需要一个绝对网址。
如何解决此冲突?任何建议表示赞赏!
答案 0 :(得分:0)
您好像是免费的Firebase游戏吗?如果是这样,您无法访问任何网络,只能使用Google API。需要启用结算功能。
您是否考虑过在FB云功能中运行Angular Universal? Angularfire Lite支持这一点,我相信Angularfire2如果不是已经太早了。也可以在没有它们的情况下完成,但可能存在一些障碍,例如在服务器上手动关闭套接字连接,在zone.runOutsideAngular等中包装东西。