【问题标题】:Angular 2 - How to use prerender.io along with lazy loadingAngular 2 - 如何使用 prerender.io 和延迟加载
【发布时间】:2017-08-04 10:52:48
【问题描述】:

由于 Angular Universal 很长一段时间内不会出现在 CLI 中,因此我必须使用 prerender.io 来让 SEO 正常工作。然而,经过一些测试,它似乎并没有那么好,因为它似乎没有等待延迟加载的模块,所以 SEO 仍然失败。

在他们的网站this location 上,他们这样说:

您的页面是否仅部分呈现?

我们的 Prerender 服务器会尽力确定页面何时完成 通过计算飞行中的请求数来加载。一旦数 飞行中的请求数达到零,我们等待一小段时间,然后 然后保存 HTML。如果这太早保存页面,您可以使用 我们的 window.prerenderReady 标志通知服务器您的页面是 可以保存了。

把它放在你的 HTML 中:

<script> window.prerenderReady = false; </script>

当我们看到 window.prerenderReady 设置为 false 时,我们会等到它 设置为 true 以保存 HTML。当您的页面将是时执行此操作 准备好(通常在 ajax 调用之后):

window.prerenderReady = true;

这是我不明白如何去做的地方。由于 Angular 从模板中删除了脚本标签(不确定这只是 CLI 行为还是 Angular 本身),我无法设置初始脚本标签。我也无法弄清楚如何在组件类的模板脚本标签内更新window 属性prerenderReady,因为我不能只使用window.prerenderReady = true 并期望它能够工作,因为必须将脚本添加到模板。

有没有人设法弄清楚这一点或对我如何实现这一点有任何想法?

【问题讨论】:

  • 你在这方面取得了成功吗?我也面临同样的问题。
  • @GirishRathod 我做了,但如果您的服务器配置正确,则不必使用此方法。
  • 我可以使用什么?请您有正确的配置示例,以便我可以使用。
  • @GirishRathod 我自己没有修复它,所以我不知道它是如何完成的:/对不起。

标签: javascript angular typescript seo prerender


【解决方案1】:

删除:server.use(prerender.removeScriptTags());

prerender.io 可以设置为保留在脚本中以便它们可以运行。

我的 Meteor-Angular2 设置给了我同样的痛苦。我的页眉和页脚模块会呈现,但不会呈现我的路由器出口输出。我放了:
&lt;script&gt; window.prerenderReady = false; &lt;/script&gt;
在我的主要 index.html 上(包含主要的 &lt;app&gt;&lt;/app&gt; 标签),并放置:
window.prerenderReady = true;
在我上次回调结束时。然后我在 prerender server 的 server.js 中注释掉了:
//server.use(prerender.removeScriptTags());
- 它终于正确呈现了。

【讨论】:

    【解决方案2】:

    好的,我得到了这个工作,但它似乎是一个相当复杂的解决方案,所以希望有人比我更聪明:)

    首先,取消注释src/polyfills.ts 中的所有浏览器polyfills(可能不是全部都需要,但我没有一个一个地测试它们):

    /** IE9, IE10 and IE11 requires all of the following polyfills. **/
    import 'core-js/es6/symbol';
    import 'core-js/es6/object';
    import 'core-js/es6/function';
    import 'core-js/es6/parse-int';
    import 'core-js/es6/parse-float';
    import 'core-js/es6/number';
    import 'core-js/es6/math';
    import 'core-js/es6/string';
    import 'core-js/es6/date';
    import 'core-js/es6/array';
    import 'core-js/es6/regexp';
    import 'core-js/es6/map';
    import 'core-js/es6/weak-map';
    import 'core-js/es6/set';
    

    接下来,您需要在您的index.html&lt;head&gt; 的脚本标签中获取您的prerenderReady 标志。 Angular 不会去掉 cmets,所以在我构建之前,我会在其中留下一个标志:

    <head>
        <!--prerender-->
    </head>
    

    现在,在您运行ng build 之后,您需要将该标志替换为实际的脚本标签。我使用 shell 脚本和sed 命令来执行此操作。比如:

    TPL="\<!--prerender--\>"
    PRERENDER_SCRIPT="\<script\>window.prerenderReady = false;\<\/script\>"
    
    # replace the comment with the actual script tag in the html file and save
    # that file's contents as a string in the INDEX_HTML variable
    INDEX_HTML=$(sed "s/$TPL/$PRERENDER_SCRIPT/g;" dist/browser/index.html);
    
    # remove the original index.html file and create an empty one in its place
    rm dist/browser/index.html
    touch dist/browser/index.html
    
    # echo the INDEX_HTML string into the new file
    echo "$INDEX_HTML" > dist/browser/index.html
    

    注意 我对在 OSX 上安装 sed 有一个模糊的回忆,但我真的不记得这些步骤了。如果您不在 linux 上并且 sed 不适合您,您只需要在 Google 上寻找解决方案。

    最后,您需要在某处将 prerenderReady 标志设置为 true。我在AppComponentOnInit 实现中这样做:

    export class AppComponent implements OnInit
    {
        ngOnInit()
        {
            window.prerenderReady = true;
        }
    }
    

    可能还值得一提的是,为了在 TypeScript 应用程序中使用 window,您需要在我称为 typings.d.ts 的文件中添加类似的内容:

    interface Window
    {
        prerenderReady:boolean;
    }
    

    以及对我放在app.module.ts 文件顶部的那个类型文件的引用:

    /// <reference path="../typings.d.ts" />
    

    希望对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-23
      • 2017-05-16
      • 2017-02-22
      • 1970-01-01
      • 1970-01-01
      • 2017-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多