在现有Node.js服务器预渲染Angular应用,实现Facebook爬虫可识别动态og标签
Hey there, let's break down why your prerender.io setup isn't working and fix it so Facebook's crawler can pick up those dynamic OG tags.
First, Fix the Prerender Middleware Order
The biggest issue here is likely the order of your Express middlewares. Prerender needs to intercept requests before your static file server or catch-all route runs, otherwise it won't get a chance to handle crawler requests. Here's how to reorder your code correctly:
const express = require('express'); const bodyParser = require('body-parser'); const path = require('path'); const http = require('http'); const app = express(); // 👉 Move prerender middleware FIRST to intercept all incoming requests app.use(require('prerender-node').set('prerenderToken', 'my-token')); // Parsers app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); // Api routes const api = require('./server/api'); app.use('/api', api); // Static files (Angular dist folder) app.use(express.static(path.join(__dirname, 'dist'))); // Catch-all route for Angular app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist/index.html')) }); // Server setup const port = process.env.PORT || '3040'; app.set('port', port); const server = http.createServer(app) server.listen(port, () => console.log('Magic happens on localhost:' + port));
Verify Prerender is Working
Next, test if prerender is actually serving the rendered HTML to crawlers. Use curl to mimic Facebook's crawler user-agent:
curl -A "facebookexternalhit/1.1" http://aramet.demo.cdots.bg/news-preview/1
Check the output HTML — if you see your dynamic OG tags (like og:title, og:image) in the <head>, then it's working. If not, move to the next checks.
Check Prerender.io Dashboard
Log into your prerender.io account and look at the Request Logs. You'll see if crawler requests are coming through, and if there are any errors (like timeouts, blocked access, or your app failing to load). Common issues here include:
- Your server is behind a firewall that blocks prerender.io's IPs
- Your Angular app takes too long to load (prerender has a default timeout)
- Dynamic data fetching in your component isn't completing before prerender captures the page
Ensure Angular's Meta Tags Load Early
Since you're using Angular 4's Meta service, make sure you're setting the OG tags as early as possible in your component lifecycle (preferably in ngOnInit). If you're fetching data from your API to populate the tags, ensure that the request completes before prerender captures the page. You might need to use async/await or ensure your observables complete before the component is considered "ready".
The fragment Meta Tag
Your <meta name="fragment" content="!"> is fine — it tells older crawlers to use the _escaped_fragment_ parameter, but modern crawlers like Facebook's use the user-agent check instead. You can leave it in place for compatibility.
Alternative: Angular Universal (If Prerender.io Fails)
If you still can't get prerender.io working, consider switching to Angular Universal (Angular's official server-side rendering solution). It runs your Angular app directly on your Node.js server, so you have full control over the rendered HTML, including dynamic OG tags. While it requires more setup than prerender-node, it's more reliable for long-term maintenance.
内容的提问来源于stack exchange,提问作者Simeon Nakov

