SSR angular 通用和 angular 8 - 在 api 完成之前渲染动态 html 内容
SSR angular universal and angular 8 - rendering dynamic html content before api completes
当我查看页面源代码时,我可以使用 angular 8 和 angular universal 为服务器端渲染动态渲染 html 但我的问题是我正在渲染动态html 在 api 请求完成加载之前,所以我无法从视图页面源中看到动态 html 中的响应 - 如果您需要任何进一步的信息,请告诉我。我 运行 这个命令:
即 npm 运行 build:ssr && npm 运行 serve:ssr
当我查看日志并更改 url 时,我在控制台中收到 [NetworkError] 但应用程序仍按预期 运行s,我需要找出一种方法来加载 api 响应,然后在请求完成后将 html 呈现到页面视图源中,但我 运行 没有想法。
希望你们中的一个能帮上忙,
谢谢
Server.ts
import 'zone.js/dist/zone-node';
import 'localstorage-polyfill';
import { join } from 'path';
import * as express from 'express';
const compression = require('compression');
const sessionStorage = require('sessionstorage');
const DIST_FOLDER = join(process.cwd(), 'dist');
const domino = require('domino');
const fs = require('fs');
const template = fs.readFileSync('./dist/browser/index.html').toString();
const win = domino.createWindow(template);
const proxy = require('http-proxy-middleware');
const cors = require('cors');
const helmet = require('helmet');
Object.assign(global, domino.impl);
(global as any)['KeyboardEvent'] = domino.impl.Event;
global['window'] = win;
global['Node'] = win.Node;
global['navigator'] = win.navigator;
global['Event'] = win.Event;
global['KeyboardEvent'] = win.Event;
global['MouseEvent'] = win.Event;
global['Event']['prototype'] = win.Event.prototype;
global['document'] = win.document;
global['sessionStorage'] = sessionStorage;
global['localStorage'] = localStorage;
// Express server
const app = express();
const PORT = process.env.PORT || 4200;
const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} = require('./dist/server/main');
app.use(cors());
app.use(compression());
// express-engine
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP)
]
}));
app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));
// Server static files from /browser
app.get('*.*', express.static(join(DIST_FOLDER, 'browser')));
// Protect website from Clickjacking attack
app.use(helmet.frameguard());
app.use(helmet.xssFilter());
// Proxy API Endpoints
app.use('/api/profileProxy', proxy(
{
target: 'http://xxxxxxx1:9004', // target host
changeOrigin: true, // needed for virtual hosted sites
// ws: true, // proxy websockets
pathRewrite: {
'^/api/profileProxy': ''
}
}
));
app.use('/api/searchProxy', proxy(
{
target: 'http://xxxxxx.160:9005', // target host
changeOrigin: true, // needed for virtual hosted sites
// ws: true, // proxy websockets
pathRewrite: {
'^/api/searchProxy': ''
}
}
));
app.get('/sitemap1.xml', function (req, res, next) {
const file = `${DIST_FOLDER}/sitemap1.xml`;
fs.exists(file, function (exists) {
if (exists) {
res.sendFile(file);
} else {
res.status(404).send('404');
}
});
});
app.get('/robots.txt', function (req, res, next) {
const file = `${DIST_FOLDER}/robots.txt`;
fs.exists(file, function (exists) {
if (exists) {
res.sendFile(file);
} else {
res.status(404).send('404');
}
});
});
// All regular routes use the Universal engine
app.get('*', (req, res) => {
console.time(`GET: ${req.originalUrl}`);
console.log(`req-QQQQQQQQQQ: ${req.originalUrl}`);
res.render(join(DIST_FOLDER, 'browser', 'index.html'), { req });
console.timeEnd(`GET: ${req.originalUrl}`);
console.log(`req-timeEnd: ${req.originalUrl}`);
});
// Start up the Node server
app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});
``
您所描述的是正常行为。只有您在 URL 栏中的原始请求(e.h。当您输入网站地址时)将使用 angular 通用进行预呈现。如果您使用查看源代码(或 Ctrl +U)
,您可以看到这个预渲染的 html
页面显示后,客户端 angular 应用程序接管。当您单击搜索按钮时,它将执行 API 调用并获取结果,这将更新页面。您会看到 html 使用浏览器调试工具中的 Html 检查器,但它不会影响服务器
发送的原始 HTML
对于可能遇到此问题的人 - 我能够通过发出 GET 请求在 SSR 的查看页面源中显示来自 api 请求的数据(在我的例子中是初始搜索结果)在我的应用程序的 app.component 中 - 谢谢
当我查看页面源代码时,我可以使用 angular 8 和 angular universal 为服务器端渲染动态渲染 html 但我的问题是我正在渲染动态html 在 api 请求完成加载之前,所以我无法从视图页面源中看到动态 html 中的响应 - 如果您需要任何进一步的信息,请告诉我。我 运行 这个命令: 即 npm 运行 build:ssr && npm 运行 serve:ssr 当我查看日志并更改 url 时,我在控制台中收到 [NetworkError] 但应用程序仍按预期 运行s,我需要找出一种方法来加载 api 响应,然后在请求完成后将 html 呈现到页面视图源中,但我 运行 没有想法。
希望你们中的一个能帮上忙, 谢谢
Server.ts
import 'zone.js/dist/zone-node';
import 'localstorage-polyfill';
import { join } from 'path';
import * as express from 'express';
const compression = require('compression');
const sessionStorage = require('sessionstorage');
const DIST_FOLDER = join(process.cwd(), 'dist');
const domino = require('domino');
const fs = require('fs');
const template = fs.readFileSync('./dist/browser/index.html').toString();
const win = domino.createWindow(template);
const proxy = require('http-proxy-middleware');
const cors = require('cors');
const helmet = require('helmet');
Object.assign(global, domino.impl);
(global as any)['KeyboardEvent'] = domino.impl.Event;
global['window'] = win;
global['Node'] = win.Node;
global['navigator'] = win.navigator;
global['Event'] = win.Event;
global['KeyboardEvent'] = win.Event;
global['MouseEvent'] = win.Event;
global['Event']['prototype'] = win.Event.prototype;
global['document'] = win.document;
global['sessionStorage'] = sessionStorage;
global['localStorage'] = localStorage;
// Express server
const app = express();
const PORT = process.env.PORT || 4200;
const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} = require('./dist/server/main');
app.use(cors());
app.use(compression());
// express-engine
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP)
]
}));
app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));
// Server static files from /browser
app.get('*.*', express.static(join(DIST_FOLDER, 'browser')));
// Protect website from Clickjacking attack
app.use(helmet.frameguard());
app.use(helmet.xssFilter());
// Proxy API Endpoints
app.use('/api/profileProxy', proxy(
{
target: 'http://xxxxxxx1:9004', // target host
changeOrigin: true, // needed for virtual hosted sites
// ws: true, // proxy websockets
pathRewrite: {
'^/api/profileProxy': ''
}
}
));
app.use('/api/searchProxy', proxy(
{
target: 'http://xxxxxx.160:9005', // target host
changeOrigin: true, // needed for virtual hosted sites
// ws: true, // proxy websockets
pathRewrite: {
'^/api/searchProxy': ''
}
}
));
app.get('/sitemap1.xml', function (req, res, next) {
const file = `${DIST_FOLDER}/sitemap1.xml`;
fs.exists(file, function (exists) {
if (exists) {
res.sendFile(file);
} else {
res.status(404).send('404');
}
});
});
app.get('/robots.txt', function (req, res, next) {
const file = `${DIST_FOLDER}/robots.txt`;
fs.exists(file, function (exists) {
if (exists) {
res.sendFile(file);
} else {
res.status(404).send('404');
}
});
});
// All regular routes use the Universal engine
app.get('*', (req, res) => {
console.time(`GET: ${req.originalUrl}`);
console.log(`req-QQQQQQQQQQ: ${req.originalUrl}`);
res.render(join(DIST_FOLDER, 'browser', 'index.html'), { req });
console.timeEnd(`GET: ${req.originalUrl}`);
console.log(`req-timeEnd: ${req.originalUrl}`);
});
// Start up the Node server
app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});
``
您所描述的是正常行为。只有您在 URL 栏中的原始请求(e.h。当您输入网站地址时)将使用 angular 通用进行预呈现。如果您使用查看源代码(或 Ctrl +U)
,您可以看到这个预渲染的 html页面显示后,客户端 angular 应用程序接管。当您单击搜索按钮时,它将执行 API 调用并获取结果,这将更新页面。您会看到 html 使用浏览器调试工具中的 Html 检查器,但它不会影响服务器
发送的原始 HTML对于可能遇到此问题的人 - 我能够通过发出 GET 请求在 SSR 的查看页面源中显示来自 api 请求的数据(在我的例子中是初始搜索结果)在我的应用程序的 app.component 中 - 谢谢