【发布时间】:2018-08-09 15:48:30
【问题描述】:
在我的一生中,我找不到适用于我的 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 看来,这似乎是我格式化 URL 的方式,但我尝试了不同的格式化方式。在第二个 fetch 语句 fetch(https://${appUrl}/) 我删除了“https://”,但 fetch 需要一个绝对 URL。
我该如何解决这个冲突?任何建议表示赞赏!
【问题讨论】:
-
使用 NGINX 和 Rendertron 的不同方法here。
标签: angular firebase fetch google-cloud-functions angular5