如果配置得当,我们可以在服务端渲染所有内容,避免在浏览器端再次调用API。首先在命令行安装AngularUniversal:ngadd@nguniversal/express-engine执行命令行npmrunbuild:ssrbrowser:是执行命令行ngbuild--prod的结果。服务器文件夹:是执行命令行ngrunPROJECT_NAME:server:production的结果。运行命令行npmrunserve:ssr,这将启动Node.jsExpress服务器,端点来自server.ts。如何避免服务端和客户端重复调用API?importTransferHttpCacheModuleandBrowserTransferStateModuleintoAppModuleimportServerTransferStateModuleintoAppServerModule查看服务端返回的HTML源码,发现里面包含serverApp-state:src/app/app.server.module.ts这个文件是自动生成的,定义了Angular应用运行在服务器端的Root模块。AppServerModule引入AppModule,以后者addon的形式工作,保证AppModule不会被修改。AppServerModule的职责:通过NoopAnimationsModule禁用动画。显然,运行在服务器端的Angular应用不需要动画效果。禁用Angular对滚动的处理修改了HTTP请求的调用方式。浏览器端HTTPAPI调用是使用XMLHttpRequest实现的,而服务器端API调用是通过xhr2(XMLHttpRequestEmulationfornode.js)完成的。文件src/main.ts也被自动修改。Angular应用程序现在仅在浏览器抛出DOMContentLoaded事件后才启动,此时HTML已被完全解析。TransferState—服务器端Angular应用程序如何在生成的Html中直接将数据传输到浏览器应用程序的机制。通过TransferState机制,服务端Angular应用通过生成的HTML源代码将数据直接传输到浏览器端应用。BrowserModule.withServerTransition({appId:'serverApp'})上面代码中的withServerTransition方法也是用来处理TransferState机制的。appId属性用于让浏览器知道在服务器端添加了哪个DOM元素。TransferState是如何工作的没有介绍TransferState机制之前的流程(1)SSRNode.js服务器接收浏览器发送的请求(2)SSR服务器调用API,读取业务数据,渲染页面。将渲染结果发送回浏览器。(3)Angular应用程序在浏览器端启动,然后再次调用API.TransferState机制一句话:服务器应用程序直接在生成的HTML中缓存API响应,浏览器在进行真正的API调用之前检查缓存的响应。服务器应用程序直接在生成的HTML中缓存API响应,浏览器在执行真正的API调用之前检查缓存的响应。直接缓存在生成的HTML代码中,浏览器在将缓存的响应发送到API之前检查它。TransferState机制的几个组成部分:TransferState:服务提供者,一个key-value存储结构。ServerTransferStateModule—导入到app.server.module.ts中。该模块在服务器应用程序中创建一个TransferState提供程序。并获取传输状态存储内容,将其转换为文本格式,存储在脚本元素中。TransferHttpCacheModule—导入app.module.ts。该模块提供了一个拦截器,可以缓存传输状态下API调用的响应数据,避免不必要的重复API调用。BrowserTransferStateModule—导入app.module.ts。从服务器应用程序读取传输状态,即脚本元素中的数据,解析它,并创建一个传输状态提供者实例。有了这一切,Angular应用程序就可以访问从服务器传输的数据。更多Jerry原创文章在这里:《王子熙》:
