我想要检测服务器端呈现的对我的页面的当前请求- ssr来自网络爬虫或普通用户。
我想在网络爬虫中做一些事情,而不是当它是用户的时候。
我想在网络爬虫访问页面以获取完整数据时运行ng-in-viewport。
而不是在用户使用我的页面时运行。
如何检测这个东西?
发布于 2020-03-29 16:01:13
最近,我和你一样面临着同样的挑战。我为我的Angular应用程序设置了SSR,并且我使用StateTransfer,以避免在用户刚刚看到来自服务器的渲染内容后在浏览器中进行相同的API调用。
我有一个视图计数器,由于页面是在服务器端呈现的,我希望避免计算爬虫生成的视图。
所以,我的结论是:
在server.ts (这是Angular SSR的标准生成文件)中,确保你从express传递的是请求对象,我的代码是这样的:
server.get('*', (req, res) => {
res.render(indexHtml, {
req, // Express request
res, // Express response
providers: [
{ provide: APP_BASE_HREF, useValue: req.baseUrl },
],
});
});然后,在您希望保留常量的任何constants.ts中,添加VIEWER注入令牌和可能的爬虫列表:
export const VIEWER = new InjectionToken<string>('viewer');
export const CRAWLER_AGENTS = [
'googlebot', 'yandexbot', 'yahoo', 'bingbot',
'baiduspider', 'facebookexternalhit', 'twitterbot', 'rogerbot',
'linkedinbot', 'embedly', 'quora link preview', 'showyoubot', 'outbrain',
'pinterest/0.', 'developers.google.com/+/web/snippet',
'slackbot', 'vkshare', 'w3c_validator', 'redditbot', 'applebot',
'whatsapp', 'flipboard', 'tumblr', 'bitlybot', 'skypeuripreview',
'nuzzel', 'discordbot', 'google page speed'
];然后,在我的app.module.ts中的providers中,我添加了新的provider,如果这是机器人或用户,它将包含信息:
import { NgModule, Optional, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { REQUEST } from '@nguniversal/express-engine/tokens';
import { CRAWLER_AGENTS, VIEWER } from './constants';
@NgModule({
imports: [ /* ... */ ],
declarations: [ /* ... */ ],
providers: [
{
provide: VIEWER,
useFactory: viewerFactory,
deps: [PLATFORM_ID, [new Optional(), REQUEST]],
},
],
})
export class AppModule {}
export function viewerFactory(platformId, req: Request): string {
if (isPlatformBrowser(platformId)) {
return 'user';
}
const userAgent = (req.get('user-agent') || '').toLowerCase();
const isCrawler = CRAWLER_AGENTS.some(crawlerAgent => userAgent.indexOf(crawlerAgent) !== -1);
return isCrawler ? 'bot' : 'user';
}可以,根据Angular documentation,您可以将提供程序的依赖项作为数组传递。我们需要Optional来防止应用程序在客户端崩溃。显然,这里不存在Express request对象。
然后在你的页面组件中,你可以像这样检查查看器:
import { Component, Inject, Optional } from '@angular/core';
@Component({
selector: 'app-article-page',
templateUrl: './article-page.component.html',
styleUrls: ['./article-page.component.scss'],
})
export class ArticlePageComponent {
constructor(
@Optional() @Inject(VIEWER) private viewer,
) {
const countViews = this.viewer !== 'bot';
}
}如果你觉得我的回答有帮助,请别忘了把它标记为已接受。
https://stackoverflow.com/questions/58505339
复制相似问题