CINXE.COM
生产环境下的 Service Worker (Service Worker) - Angular 中文开发手册 - 开发者手册 - 腾讯云开发者社区-腾讯云
<!DOCTYPE html><html munual-autotracker-init="" qct-pv-id="UaoV2kM8qwrMUPSHf_ZUd" qct-ip="8.222.208.146"><head><meta charSet="UTF-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><title>生产环境下的 Service Worker (Service Worker) - Angular 中文开发手册 - 开发者手册 - 腾讯云开发者社区-腾讯云</title><meta name="keywords" content="Service Worker,Angular教程,Angular,Service Worker 开发文档,Service Worker 中文文档"/><meta name="subjectTime" content="2017-01-01 00:00:00"/><meta name="description" content=""/><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover"/><meta name="format-detection" content="telephone=no"/><link rel="canonical" href="https://cloud.tencent.com/developer/section/1489572"/><link rel="stylesheet" href="//cloudcache.tencent-cloud.cn/open_proj/proj_qcloud_v2/gateway/portal/css/global-20209142343.css"/><link rel="stylesheet" href="//cloudcache.tencent-cloud.cn/qcloud/ui/cloud-community/build/base/base-202410111735.css"/><link rel="stylesheet" href="//cloudcache.tencent-cloud.cn/open_proj/proj_qcloud_v2/community-pc/build/AskDialog/AskDialog-202204021635.css?max_age=31536000"/><link rel="stylesheet" href="//cloudcache.tencent-cloud.cn/open_proj/proj_qcloud_v2/community-pc/build/AskDialog/AskDialog-202204021635.css?max_age=31536000"/><link rel="stylesheet" href="//cloudcache.tencent-cloud.cn/qcloud/ui/community-pc/build/base/base-202412201223.css"/><link rel="stylesheet" href="//cloudcache.tencent-cloud.cn/qcloud/ui/cloud-community/build/base/base-202410111735.css"/><link rel="stylesheet" href="//cloudcache.tencent-cloud.cn/open_proj/proj_qcloud_v2/community/portal/css/markdown-201810241044.css?max_age=31536000"/><link rel="stylesheet" href="//cloudcache.tencent-cloud.cn/open_proj/proj_qcloud_v2/community/portal/css/documents/documents-20189191454.css?max_age=31536000"/><link rel="stylesheet" href="//cloudcache.tencent-cloud.cn/qcloud/draft-master/dist/draft-master-v2.0.165.d4s2ddo9sb.css?max_age=31536000"/><style media="screen">@supports (padding:max(0px)){.set-safe-area .com-main{bottom:calc(max(12px,constant(safe-area-inset-bottom)) + 50px);bottom:calc(max(12px,env(safe-area-inset-bottom)) + 50px)}.set-safe-area .com-main-simple-sec,.set-safe-area .com-main.without-tab-ft,.set-safe-area .com-main.without-ft{bottom:max(12px,constant(safe-area-inset-bottom));bottom:max(12px,env(safe-area-inset-bottom))}.set-safe-area .com-main-sec{bottom:max(12px,constant(safe-area-inset-bottom));bottom:max(12px,env(safe-area-inset-bottom))}.set-safe-area .com-m-footer,.set-safe-area .sa-fixed-btns{bottom:max(12px,constant(safe-area-inset-bottom));bottom:max(12px,env(safe-area-inset-bottom))}.set-safe-area .com-mobile-body{bottom:max(12px,constant(safe-area-inset-bottom));bottom:max(12px,env(safe-area-inset-bottom))}}@supports (padding:max(0px)){.set-safe-area .support-wrap,.set-safe-area div.body{bottom:max(12px,constant(safe-area-inset-bottom));bottom:max(12px,env(safe-area-inset-bottom))}.set-safe-area .com-responsive-no-ft div.body{bottom:max(12px,constant(safe-area-inset-bottom));bottom:max(12px,env(safe-area-inset-bottom))}}.doc-con .J-docShareModal{display: none;} .doc-con .J-docShareCopyTipModalMB{display: none} .with-focus+.com-main-simple-sec, .with-focus+.com-main,.with-focus+.com-body,.with-focus+.qa-body{top:100px} .qa-detail-ask-panel:after{display:none!important;} .sa-fixed-btns .c-btn-weak{background-color: #fff;} .qa-r-editor.draft-editor-host.rno-markdown{height: 290px;overflow-y:auto;} .uc-achievement{line-height:24px;margin-bottom:5px;white-space: initial;overflow:visible;text-overflow:initial} .uc-achievement .uc-achievement-icon{top:0;margin-top:0;}</style></head><body style="position:initial"><div id="react-root" class=""><div class=""><div class="cdc-header is-fixed"><div class="cdc-header__placeholder"></div><div class="cdc-header__inner"><div class="cdc-header__top"><div class="cdc-header__top-left"><a href="/?from=20060&from_column=20060" target="_blank" class="cdc-header__top-logo"><i>腾讯云</i></a><div class="cdc-header__top-line"></div><a href="/developer" class="cdc-header__top-logo community"><i>开发者社区</i></a><div class="cdc-header__activity"><div id="cloud-header-product-container"></div></div></div><div class="cdc-header__top-operates"><a href="/document/product?from=20702&from_column=20702" target="_blank" class="cdc-header__link">文档</a><a href="/voc/?from=20703&from_column=20703" target="_blank" class="cdc-header__link">建议反馈</a><a href="https://console.cloud.tencent.com?from=20063&from_column=20063" target="_blank" class="cdc-header__link" track-click="{"areaId":102001,"subAreaId":1}">控制台</a><div class="cdc-header__account"><div class="cdc-header__account-inner"><button class="cdc-btn cdc-header__account-btn cdc-btn--primary">登录/注册</button></div></div></div></div><div class="cdc-header__bottom"><div class="cdc-header__bottom-nav"><a href="/developer" class="cdc-header__bottom-home">首页</a><div class="cdc-header__nav-list"><div class="cdc-header__nav-item">学习</div><div class="cdc-header__nav-item">活动</div><div class="cdc-header__nav-item">专区</div><div class="cdc-header__nav-item">工具</div></div><a href="/tvp?from=20154&from_column=20154" class="cdc-header__tvp" target="_blank">TVP</a><div class="cdc-header__activity"><a class="cdc-header__activity-tit" href="/act?from=20061&from_column=20061" target="_blank">最新优惠活动<div class="cdc-badge"><div class="cdc-badge-inner"><div class="cdc-badge-text"></div></div></div></a></div><div id="community-header-product-container"></div></div><div class="cdc-header__bottom-operates"><div class="cdc-header__search"><div class="cdc-search__wrap"><div class="cdc-search"><span class="cdc-search__text">文章/答案/技术大牛</span><button class="cdc-search__btn">搜索<i class="cdc-search__i search"></i></button></div><div class="cdc-search__dropdown"><div class="cdc-search__bar"><input type="text" class="cdc-search__bar-input" placeholder="文章/答案/技术大牛" value=""/><div class="cdc-search__bar-btns"><button class="cdc-search__btn">搜索<i class="cdc-search__i search"></i></button><button class="cdc-search__btn">关闭<i class="cdc-search__i clear"></i></button></div></div></div></div></div><div class="cdc-header__create"><span class="cdc-header__create-btn not-logged"><span class="cdc-svg-icon-con"><span class="cdc-svg-icon" style="line-height:1;color:#0052D9;width:16px;height:16px"><svg width="16" height="16" viewBox="0 0 16 16" fill="currentcolor" xmlns="http://www.w3.org/2000/svg"><path d="M14.2466 12.0145C14.1698 13.6258 12.8381 14.9131 11.2129 14.9131H11.1579H4.0927H4.03772C2.4125 14.9131 1.08014 13.6258 1.00334 12.0145H1V11.8668V4.07213V4.04627V3.89922H1.00334C1.08014 2.28732 2.4125 1 4.03772 1H9.6473V1.00069H10.0786L8.7688 2.10773H8.43888H7.7916H6.37904H4.03772C2.97234 2.10773 2.10445 2.9777 2.10445 4.04629V4.41869V4.4472V6.39498V11.4269V11.4309V11.8668C2.10445 12.9354 2.97234 13.8053 4.03772 13.8053H6.37904H8.87153H11.2129C12.2782 13.8053 13.1461 12.9355 13.1461 11.8668V11.466V11.454V9.5181V6.39364L14.2506 5.3051V11.8668V12.0145H14.2466ZM10.4324 7.15226L9.63146 7.99761C9.36577 8.2693 8.69326 8.95104 8.48066 9.17631C8.26726 9.40288 8.09039 9.58901 7.95061 9.73544C7.81079 9.88188 7.72667 9.96597 7.70083 9.98656C7.63321 10.0488 7.55703 10.1144 7.47022 10.1846C7.38412 10.2542 7.29404 10.3099 7.20063 10.3516C7.10722 10.4007 6.97072 10.459 6.79049 10.5305C6.61028 10.6001 6.42213 10.6676 6.22468 10.7339C6.02792 10.8002 5.84109 10.8571 5.66484 10.9061C5.48795 10.9538 5.3561 10.9863 5.2693 11.0009C5.08977 11.0214 4.96988 10.993 4.90956 10.9168C4.84931 10.8405 4.83276 10.7107 4.85924 10.5312C4.87315 10.4331 4.9043 10.292 4.95468 10.1078C5.00431 9.92297 5.05802 9.7315 5.11431 9.53341C5.1713 9.33526 5.22629 9.15179 5.27926 8.98484C5.33297 8.8179 5.37599 8.7026 5.40978 8.64032C5.44953 8.54357 5.49463 8.45413 5.54495 8.37399C5.59465 8.29379 5.66616 8.20503 5.75965 8.10766C5.79934 8.06588 5.89281 7.96649 6.03988 7.81018C6.18624 7.65311 6.80114 7.02774 7.02104 6.79783L7.75117 6.03524L8.56212 5.1899L10.6345 3.02466L12.5214 4.93874L10.4324 7.15226ZM13.816 3.58581C13.7166 3.68987 13.6272 3.78064 13.5483 3.85883C13.4694 3.93703 13.4006 4.0066 13.3423 4.06686C13.276 4.13643 13.2144 4.19738 13.1561 4.24903L11.2785 2.33569C11.3785 2.24025 11.4965 2.12565 11.6336 1.99115C11.7707 1.85668 11.8854 1.75061 11.9761 1.67242C12.0934 1.57708 12.2133 1.51013 12.3385 1.47109C12.4525 1.43529 12.5644 1.41805 12.6751 1.41876H12.7056C12.7665 1.42139 12.8268 1.42729 12.8851 1.43724C12.8838 1.4366 12.8811 1.43724 12.8798 1.4366C12.8811 1.4366 12.8838 1.4366 12.8851 1.43724C13.1376 1.48428 13.4019 1.62009 13.6265 1.83743C13.7511 1.95871 13.8524 2.09382 13.9259 2.23296C14.0346 2.43834 14.0863 2.65304 14.0763 2.8491C14.0763 2.87294 14.0783 2.89748 14.0783 2.92201C14.0783 3.03529 14.0571 3.14789 14.0154 3.26055C13.9737 3.37314 13.9067 3.48185 13.816 3.58581Z" fill="#0052D9"></path></svg></span></span>发布<span class="cdc-svg-icon-con cdc-header__create-btn-arrow"><span class="cdc-svg-icon" style="line-height:1;color:inherit;width:16px;height:16px"><svg width="16" height="16" viewBox="0 0 16 16" fill="currentcolor" xmlns="http://www.w3.org/2000/svg"><path d="M8.16377 4L9.57798 5.41421L14.5277 10.364L13.1135 11.7782L8.1638 6.829L3.21402 11.7782L1.7998 10.364L8.16377 4Z"></path></svg></span></span></span></div></div></div></div></div><div class="cdc-m-header with-focus is-fixed"><div class="cdc-m-header__placeholder"></div><div class="cdc-m-header__inner"><div class="cdc-m-guider-banner is-sticky"><div class="cdc-m-guider-banner__guide-mvp" track-exposure="{"areaId":118000}" track-click="{"areaId":118000}"><div class="cdc-m-guider-banner__guide-mvp-text">精选内容/技术社群/优惠产品,<em>尽在小程序</em></div><div class="cdc-m-guider-banner__guide-mvp-btn">立即前往</div></div></div><div class="cdc-m-header__main"><div class="cdc-m-header__trigger"></div><div class="cdc-m-header__logo"><i class="cdc-m-header__logo-icon"></i></div><div class="cdc-m-header__search"><i class="cdc-m-header__search-icon"></i></div><div class="cdc-m-header__operate"><span class="cdc-m-header__operate-icon"></span></div></div></div></div><div class="J-body"><section class="doc-layout"><aside class="J-doc-aside-menu doc-aside"><div class="doc-aside-search"><div class="com-search-bar"><label class="com-search"><input type="text" placeholder="搜索" class="search-input" value="" maxLength="50"/><button type="button" class="search-btn">搜索</button></label></div></div><div class="J-doc-aside-inner doc-aside-inner"><div class="c-tree-view"><ul class="c-tree c-tree-level1"><li id="doc.1018" class="c-tree-item"><a href="/developer/doc/1018" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/ee986e17811d33bae535a2eb2647ecb1.png')"></i><span class="c-tree-text">Bootstrap 4</span></div></a></li><li id="doc.1019" class="c-tree-item"><a href="/developer/doc/1019" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/ee986e17811d33bae535a2eb2647ecb1.png')"></i><span class="c-tree-text">Bootstrap 3</span></div></a></li><li id="doc.1023" class="c-tree-item"><a href="/developer/doc/1023" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/bbd212b11fd3c3fab460eccd54327b6f.png')"></i><span class="c-tree-text">C</span></div></a></li><li id="doc.1024" class="c-tree-item"><a href="/developer/doc/1024" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/09d05f338c9c12c5b10679ab3bc5a371.png')"></i><span class="c-tree-text">C++</span></div></a></li><li id="doc.1037" class="c-tree-item"><a href="/developer/doc/1037" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/aa9ae1024cdb3dbeba059f46468a8d23.png')"></i><span class="c-tree-text">Clojure 1.8</span></div></a></li><li id="doc.1046" class="c-tree-item"><a href="/developer/doc/1046" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/fdd164a44e34c771dcfdabd27e1138b5.png')"></i><span class="c-tree-text">Codeigniter 3</span></div></a></li><li id="doc.1052" class="c-tree-item"><a href="/developer/doc/1052" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/199d202a2a225d118d8df17338635682.png')"></i><span class="c-tree-text">CSS</span></div></a></li><li id="doc.1060" class="c-tree-item"><a href="/developer/doc/1060" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/9f076c75e8aaf04b5a6656982c893ffa.png')"></i><span class="c-tree-text">Docker 17</span></div></a></li><li id="doc.1070" class="c-tree-item"><a href="/developer/doc/1070" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/65668d05b89ba9823e6f36a1a6dda6c5.png')"></i><span class="c-tree-text">Electron</span></div></a></li><li id="doc.1071" class="c-tree-item"><a href="/developer/doc/1071" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/21d7d051e70beb27eb0a961cd948a48d.png')"></i><span class="c-tree-text">Elixir 1.5</span></div></a></li><li id="doc.1075" class="c-tree-item"><a href="/developer/doc/1075" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/20f24c9aaa55d7a1b99ad4a141418cca.png')"></i><span class="c-tree-text">Erlang 20</span></div></a></li><li id="doc.1078" class="c-tree-item"><a href="/developer/doc/1078" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/ddd98094fdaabf06c8c60f1e51935860.png')"></i><span class="c-tree-text">Eslint</span></div></a></li><li id="doc.1079" class="c-tree-item"><a href="/developer/doc/1079" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/c7e9393951ddb914a7af947a0b76d566.png')"></i><span class="c-tree-text">Express</span></div></a></li><li id="doc.1096" class="c-tree-item"><a href="/developer/doc/1096" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/3b9881490538872ca8acfb9c757d536c.png')"></i><span class="c-tree-text">Git</span></div></a></li><li id="doc.1101" class="c-tree-item"><a href="/developer/doc/1101" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/d4561739a3aa0ebb492202ed004f6845.png')"></i><span class="c-tree-text">Go</span></div></a></li><li id="doc.1116" class="c-tree-item"><a href="/developer/doc/1116" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/8281f39e6bb68d4ea66a11ae0c35064e.png')"></i><span class="c-tree-text">HTML</span></div></a></li><li id="doc.1117" class="c-tree-item"><a href="/developer/doc/1117" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/553dd829cd43b9b4b0210d27ad1ffea2.png')"></i><span class="c-tree-text">HTTP</span></div></a></li><li id="doc.1118" class="c-tree-item"><a href="/developer/doc/1118" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/142bb955cebe43dcd15ec5872825cbdf.png')"></i><span class="c-tree-text">Immutable 3.8.1</span></div></a></li><li id="doc.1121" class="c-tree-item"><a href="/developer/doc/1121" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/e7765f3f09d213b1e9a69a5d14ee0a18.png')"></i><span class="c-tree-text">JavaScript</span></div></a></li><li id="doc.1138" class="c-tree-item"><a href="/developer/doc/1138" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/05f5d001238a1ca847c0a29273fb3fdf.png')"></i><span class="c-tree-text">Lodash 4</span></div></a></li><li id="doc.1141" class="c-tree-item"><a href="/developer/doc/1141" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/fe45b8dbc693fd39062c172e06206317.png')"></i><span class="c-tree-text">Lua 5.3</span></div></a></li><li id="doc.1158" class="c-tree-item"><a href="/developer/doc/1158" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/ad00984cfb056d48f054f0b68f0a1ae7.png')"></i><span class="c-tree-text">Nginx</span></div></a></li><li id="doc.1187" class="c-tree-item"><a href="/developer/doc/1187" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/b5d5961eeb147bfc9a935f2fdb76eaa7.png')"></i><span class="c-tree-text">PHP</span></div></a></li><li id="doc.1188" class="c-tree-item"><a href="/developer/doc/1188" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/1e49d3c8513bf0e7752f74c6dc1efeab.png')"></i><span class="c-tree-text">Phpunit 6</span></div></a></li><li id="doc.1198" class="c-tree-item"><a href="/developer/doc/1198" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/c8a0c79bd0559c257793ad02704dfad4.png')"></i><span class="c-tree-text">Python</span></div></a></li><li id="doc.1201" class="c-tree-item"><a href="/developer/doc/1201" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/5c5afe657e4cd0cab6601b5bb1ec9272.png')"></i><span class="c-tree-text">React</span></div></a></li><li id="doc.1202" class="c-tree-item"><a href="/developer/doc/1202" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/5c5afe657e4cd0cab6601b5bb1ec9272.png')"></i><span class="c-tree-text">React native</span></div></a></li><li id="doc.1203" class="c-tree-item"><a href="/developer/doc/1203" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/23bd9465961c415348ddffae0ee80849.png')"></i><span class="c-tree-text">Redis</span></div></a></li><li id="doc.1204" class="c-tree-item"><a href="/developer/doc/1204" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/aac9c7da445187766d7b8974a4478a79.png')"></i><span class="c-tree-text">Redux</span></div></a></li><li id="doc.1211" class="c-tree-item"><a href="/developer/doc/1211" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/b0da03eeec7c332e2b9615934a2d957e.png')"></i><span class="c-tree-text">Ruby 2.4</span></div></a></li><li id="doc.1220" class="c-tree-item"><a href="/developer/doc/1220" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/27f436e35d9b36d4bdd245fd2c7d5a17.png')"></i><span class="c-tree-text">Sass</span></div></a></li><li id="doc.1221" class="c-tree-item"><a href="/developer/doc/1221" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/32c59e4a9b8eab095c26f394ac149b62.png')"></i><span class="c-tree-text">Scikit image</span></div></a></li><li id="doc.1227" class="c-tree-item"><a href="/developer/doc/1227" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/620ef1d0948e33eab98eef2c0440d145.png')"></i><span class="c-tree-text">Socket.IO</span></div></a></li><li id="doc.1228" class="c-tree-item"><a href="/developer/doc/1228" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/132cebf267aea6854ab033a1a6e6592e.png')"></i><span class="c-tree-text">Sqlite</span></div></a></li><li id="doc.1231" class="c-tree-item"><a href="/developer/doc/1231" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/800ff82933f9bd5eee1b18d1955bd476.png')"></i><span class="c-tree-text">SVG</span></div></a></li><li id="doc.1241" class="c-tree-item"><a href="/developer/doc/1241" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/efd0b60404a54763ae096c4176e9d2e6.png')"></i><span class="c-tree-text">TensorFlow Guide</span></div></a></li><li id="doc.1244" class="c-tree-item"><a href="/developer/doc/1244" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/1381358584ecd0a15becada8f8e2017b.png')"></i><span class="c-tree-text">Typescript</span></div></a></li><li id="doc.1245" class="c-tree-item"><a href="/developer/doc/1245" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/6f46eb25195d526f06700a3aa8cc3485.png')"></i><span class="c-tree-text">Underscore</span></div></a></li><li id="doc.1247" class="c-tree-item"><a href="/developer/doc/1247" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/dcc267ca87a633f395baa593a3dd899d.png')"></i><span class="c-tree-text">Vue 2</span></div></a></li><li id="doc.1250" class="c-tree-item"><a href="/developer/doc/1250" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/5f8c9e286f7ca994db07ef8803bba9e8.png')"></i><span class="c-tree-text">Webpack</span></div></a></li><li id="doc.1252" class="c-tree-item"><a href="/developer/doc/1252" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/8c05850b2e13a75546f6c8a1fb7648ef.png')"></i><span class="c-tree-text">Xslt & Xpath</span></div></a></li><li id="doc.1253" class="c-tree-item"><a href="/developer/doc/1253" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/6783dcd935b3976111d85c408df944d7.png')"></i><span class="c-tree-text">Yarn</span></div></a></li><li id="doc.1257" class="c-tree-item"><a href="/developer/doc/1257" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/3834d5e3369eba9f19b64bac1d89d194.png')"></i><span class="c-tree-text">RxJS 5</span></div></a></li><li id="doc.1258" class="c-tree-item"><a href="/developer/doc/1258" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/4ae7011e33bd5fc4e6255a5525bf6cc1.png')"></i><span class="c-tree-text">Rollup.js</span></div></a></li><li id="doc.1260" class="c-tree-item"><a href="/developer/doc/1260" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/091b6c7bc470a4553017a47fdc9c5b5a.png')"></i><span class="c-tree-text">Babel </span></div></a></li><li id="doc.1261" class="c-tree-item"><a href="/developer/doc/1261" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/60b3c2cd3a70a8aae4358a2c5e3821e3.png')"></i><span class="c-tree-text">Parcel</span></div></a></li><li id="doc.1262" class="c-tree-item"><a href="/developer/doc/1262" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/b81b145550929479699e54c3b1f207bb.png')"></i><span class="c-tree-text">MobX</span></div></a></li><li id="doc.1263" class="c-tree-item"><a href="/developer/doc/1263" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/6e14af5a5cc799e479a21c795e0bbfa4.png')"></i><span class="c-tree-text">Koa</span></div></a></li><li id="doc.1264" class="c-tree-item"><a href="/developer/doc/1264" class="c-tree-title tree-open"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/e8c49341c863b1adcc85af2b6a2069db.png')"></i><span class="c-tree-text">Angular</span></div></a><ul class="c-tree c-tree-level2"><li id="chapter.17995-doc.1264" class="c-tree-item"><a href="/developer/chapter/17995" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">快速上手 | quick start </span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.17996-doc.1264" class="c-tree-item"><a href="/developer/chapter/17996" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text"> 教程 | Tutorial</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.17997-doc.1264" class="c-tree-item"><a href="/developer/chapter/17997" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">架构 </span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.17998-doc.1264" class="c-tree-item"><a href="/developer/chapter/17998" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">组件与模板</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.17999-doc.1264" class="c-tree-item"><a href="/developer/chapter/17999" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">表单 </span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18000-doc.1264" class="c-tree-item"><a href="/developer/chapter/18000" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">可观察对象与RxJS </span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18001-doc.1264" class="c-tree-item"><a href="/developer/chapter/18001" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">引导启动</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18002-doc.1264" class="c-tree-item"><a href="/developer/chapter/18002" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">Angular 模块</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18003-doc.1264" class="c-tree-item"><a href="/developer/chapter/18003" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">依赖注入</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18004-doc.1264" class="c-tree-item"><a href="/developer/chapter/18004" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">HttpClient</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18005-doc.1264" class="c-tree-item"><a href="/developer/chapter/18005" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">路由与导航</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18006-doc.1264" class="c-tree-item"><a href="/developer/chapter/18006" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">测试</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18008-doc.1264" class="c-tree-item"><a href="/developer/chapter/18008" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">国际化</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18009-doc.1264" class="c-tree-item"><a href="/developer/chapter/18009" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">语言服务</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18010-doc.1264" class="c-tree-item"><a href="/developer/chapter/18010" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">安全</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18011-doc.1264" class="c-tree-item"><a href="/developer/chapter/18011" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">环境准备与部署</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18012-doc.1264" class="c-tree-item"><a href="/developer/chapter/18012" class="c-tree-title tree-open"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">Service Worker</span></div></a><ul class="c-tree c-tree-level3"><li id="section.1489569-chapter.18012-doc.1264" class="c-tree-item"><a href="/developer/section/1489569" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-icon"></i><span class="c-tree-text">简介</span></div></a></li><li id="section.1489570-chapter.18012-doc.1264" class="c-tree-item"><a href="/developer/section/1489570" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-icon"></i><span class="c-tree-text">快速起步</span></div></a></li><li id="section.1489571-chapter.18012-doc.1264" class="c-tree-item"><a href="/developer/section/1489571" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-icon"></i><span class="c-tree-text">与 Service Worker 通讯</span></div></a></li><li id="section.1489572-chapter.18012-doc.1264" class="c-tree-item"><a href="/developer/section/1489572" class="c-tree-title tree-hover tree-actived"><div class="c-tree-title-inner"><i class="c-tree-icon"></i><span class="c-tree-text">生产环境下的 Service Worker</span></div></a></li><li id="section.1489573-chapter.18012-doc.1264" class="c-tree-item"><a href="/developer/section/1489573" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-icon"></i><span class="c-tree-text">Service Worker 配置</span></div></a></li></ul></li><li id="chapter.18013-doc.1264" class="c-tree-item"><a href="/developer/chapter/18013" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">保持最新 </span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18014-doc.1264" class="c-tree-item"><a href="/developer/chapter/18014" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">从 AngularJS 升级</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18015-doc.1264" class="c-tree-item"><a href="/developer/chapter/18015" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">服务端渲染</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18016-doc.1264" class="c-tree-item"><a href="/developer/chapter/18016" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">Visual Studio 2015 快速上手</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18017-doc.1264" class="c-tree-item"><a href="/developer/chapter/18017" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">风格指南</span></div></a><ul class="c-tree c-tree-level3"></ul></li><li id="chapter.18018-doc.1264" class="c-tree-item"><a href="/developer/chapter/18018" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon"></i><span class="c-tree-text">词汇表</span></div></a><ul class="c-tree c-tree-level3"></ul></li></ul></li><li id="doc.1265" class="c-tree-item"><a href="/developer/doc/1265" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/caf6b28113950ce4340e06359f49a504.png')"></i><span class="c-tree-text">Gulp</span></div></a></li><li id="doc.1266" class="c-tree-item"><a href="/developer/doc/1266" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/420c7fbb54021275fd17d9c5d1ea2b85.png')"></i><span class="c-tree-text">Grunt</span></div></a></li><li id="doc.1267" class="c-tree-item"><a href="/developer/doc/1267" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/0689f2d1c5100b25abee6b0dadfbb486.png')"></i><span class="c-tree-text">Stylelint</span></div></a></li><li id="doc.1268" class="c-tree-item"><a href="/developer/doc/1268" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/5ef71d8183d09dd0f1dac7c518f3a3cb.png')"></i><span class="c-tree-text">Standard JS </span></div></a></li><li id="doc.1270" class="c-tree-item"><a href="/developer/doc/1270" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/c1e4f4dbc9f8d54cbbdb94da8a38d6f9.svg')"></i><span class="c-tree-text"> Element UI</span></div></a></li><li id="doc.1271" class="c-tree-item"><a href="/developer/doc/1271" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/2fe503f4c2b328ff294afcee60501005.svg')"></i><span class="c-tree-text">iView UI</span></div></a></li><li id="doc.1272" class="c-tree-item"><a href="/developer/doc/1272" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/0fa336e3bd3b9a45bc0d5f1db0fcda38.svg')"></i><span class="c-tree-text">Lavas</span></div></a></li><li id="doc.1273" class="c-tree-item"><a href="/developer/doc/1273" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/1100f38ef1f4ea051d57e26c2466db85.svg')"></i><span class="c-tree-text">Mint UI</span></div></a></li><li id="doc.1278" class="c-tree-item"><a href="/developer/doc/1278" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/729abeb836afaf86d93dab798353d82c.svg')"></i><span class="c-tree-text">PostCSS </span></div></a></li><li id="doc.1279" class="c-tree-item"><a href="/developer/doc/1279" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/5aa23e8c0965e282fa43c5712dd0d935.svg')"></i><span class="c-tree-text">ThinkJS</span></div></a></li><li id="doc.1281" class="c-tree-item"><a href="/developer/doc/1281" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/0997355bc7bde23cf1faccc32b5de571.png')"></i><span class="c-tree-text">Nest</span></div></a></li><li id="doc.1282" class="c-tree-item"><a href="/developer/doc/1282" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/68cb6e2d8b03494a4913c27fa0835c7e.svg')"></i><span class="c-tree-text">npm</span></div></a></li><li id="doc.1292" class="c-tree-item"><a href="/developer/doc/1292" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/3199368d55b8dfc8617e2a562a50b993.png')"></i><span class="c-tree-text">Node.js教程</span></div></a></li><li id="doc.1293" class="c-tree-item"><a href="/developer/doc/1293" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/ab7df92584b878ceb24ae515ce81f172.png')"></i><span class="c-tree-text">JSON教程</span></div></a></li><li id="doc.1309" class="c-tree-item"><a href="/developer/doc/1309" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/9c00f5630270408b01e6442cc74891e2.png')"></i><span class="c-tree-text">Groovy教程</span></div></a></li><li id="doc.1320" class="c-tree-item"><a href="/developer/doc/1320" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/bf0e56f8f95181d143733f3e698b09e0.png')"></i><span class="c-tree-text">vb.net教程</span></div></a></li><li id="doc.1322" class="c-tree-item"><a href="/developer/doc/1322" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/258beb187a7bd054e9660415c5a4cb70.png')"></i><span class="c-tree-text">Storm入门教程</span></div></a></li><li id="doc.1324" class="c-tree-item"><a href="/developer/doc/1324" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/3203d6a0f9ed96d2672fde70acbd45a4.png')"></i><span class="c-tree-text">Hibernate 教程</span></div></a></li><li id="doc.1325" class="c-tree-item"><a href="/developer/doc/1325" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/a8185507ff066fd9b56db06acf411ef1.png')"></i><span class="c-tree-text">Slick教程</span></div></a></li><li id="doc.1326" class="c-tree-item"><a href="/developer/doc/1326" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/38302d41331de90d0de1303851193a0e.png')"></i><span class="c-tree-text">MongoDB教程</span></div></a></li><li id="doc.1407" class="c-tree-item"><a href="/developer/doc/1407" class="c-tree-title"><div class="c-tree-title-inner"><i class="c-tree-arrow"></i><i class="c-tree-icon" style="background-image:url('https://main.qcloudimg.com/raw/d81c32ff85716189b65c20405d555962.png')"></i><span class="c-tree-text">Yii 2.0</span></div></a></li></ul></div></div></aside><div class="doc-main"><nav class=" J-doc-crumb doc-crumb"><a href="/developer/doc/1264" class="doc-crumb-item"><i class="crumb-icon" style="background-image:url(https://main.qcloudimg.com/raw/e8c49341c863b1adcc85af2b6a2069db.png)"></i>Angular</a><span class="doc-crumb-split"></span><a href="/developer/chapter/18012" class="doc-crumb-item">Service Worker</a><span class="doc-crumb-split"></span><span class="doc-crumb-item">生产环境下的 Service Worker</span></nav><div class="J-doc-main doc-main-inner"><div class="doc-main-content"><header class="doc-main-hd"><div class="hd-cnt"><h1 class="hd-title">生产环境下的 Service Worker</h1></div></header><div class="c-markdown doc-markdown"><div><div id="stage-100056131" class="J-stage-100056131 doc-postil"><div><div class="rno-markdown undefined rno-"><p>本页讲的是如何使用 Angular Service Worker 发布和支持生产环境下的应用。 它解释了 Angular Service Worker 如何满足大规模生产环境的需求、Service Worker 在多种条件下有哪些行为以及有哪些可用的资源和故障保护机制。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056132" class="J-stage-100056132 doc-postil"><div><div class="rno-markdown undefined rno-"><h4>前提条件</h4></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056133" class="J-stage-100056133 doc-postil"><div><div class="rno-markdown undefined rno-"><p>对下列知识有基本的了解:</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056134" class="J-stage-100056134 doc-postil"><div><div class="rno-markdown undefined rno-"><ul class="ul-level-0"><li><a class="" href="/developer/tools/blog-entry?target=https%3A%2F%2Fangular.cn%2Fguide%2Fservice-worker-communications&objectId=undefined&objectType=" target="_blank" rel="nofollow noopener noreferrer">与 Service Worker 通讯</a>.</li></ul></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056136" class="J-stage-100056136 doc-postil"><div><div class="rno-markdown undefined rno-"><h2>Service Worker 与应用资源的缓存</h2></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056137" class="J-stage-100056137 doc-postil"><div><div class="rno-markdown undefined rno-"><p>从概念上说,你可以把 Angular Service Worker 想象成一个转发式缓存或装在最终用户浏览器中的 CDN 边缘。 Service Worker 的工作是从本地缓存中满足 Angular 应用对资源或数据的请求,而不用等待网络。 和所有缓存一样,它有一些规则来决定内容该如何过期或更新。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056138" class="J-stage-100056138 doc-postil"><div><div class="rno-markdown undefined rno-"><h3>应用的版本</h3></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056139" class="J-stage-100056139 doc-postil"><div><div class="rno-markdown undefined rno-"><p>在 Angular Service Worker 的语境下,“版本”是指用来表示 Angular 应用的某一次构建成果的一组资源。 当应用的一个新的构建发布时,Service Worker 就把它看做此应用的一个新版本。 就算只修改了一个文件,也同样如此。 在任何一个给定的时间,Service Worker 可能会在它的缓存中拥有此应用的多个版本,这几个版本也都能用于提供服务。 要了解更多,参见稍后的 <a class="" href="/developer/tools/blog-entry?target=https%3A%2F%2Fangular.cn%2Fguide%2Fservice-worker-devops%23tabs&objectId=undefined&objectType=" target="_blank" rel="nofollow noopener noreferrer">App 选项卡</a>。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056140" class="J-stage-100056140 doc-postil"><div><div class="rno-markdown undefined rno-"><p>要保持应用的整体性,Angular Service Worker 会用所有的文件共同组成一个版本。 组成版本的这些文件通常包括 HTML、JS 和 CSS 文件。把这些文件分成一组是至关重要的,因为它们会互相引用,并且依赖于一些特定内容。 比如,<code>index.html</code> 文件可能有个引用 <code>bundle.js</code> 的 <code><script></code>标签,它可能会试图从这个脚本中调用一个 <code>startApp()</code> 函数。 任何时候,只要这个版本的 <code>index.html</code> 被提供了,与它对应的 <code>bundle.js</code> 也必须同时提供。 这种情况下,使用调用了 <code>startApp()</code> 的老的 <code>index.html</code>并同时使用定义了 <code>runApp()</code> 的新 bundle 就是无效的。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056141" class="J-stage-100056141 doc-postil"><div><div class="rno-markdown undefined rno-"><p>当使用惰性加载模块时,文件的整体性就显得格外重要。 某个 JS 包可能引用很多惰性块,而这些惰性块的文件名在应用的每次特定的构建中都是唯一的。 如果运行应用的 <code>X</code> 版本视图加载一个惰性块,但该块的服务器已经升级到了 <code>X + 1</code>版本,这次惰性加载操作就会失败。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056142" class="J-stage-100056142 doc-postil"><div><div class="rno-markdown undefined rno-"><p>本应用的版本标识符由其所有资源的内容决定,如果它们中的任何一个发生了变化,则版本标识符也随之改变。 实际上,版本是由 <code>ngsw.json</code> 文件的内容决定的,包含了所有已知内容的哈希值。 如果任何一个被缓存的文件发生了变化,则该文件的哈希也将在<code>ngsw.json</code>中随之变化,从而导致 Angular Service Worker 将这个活动文件的集合视为一个新版本。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056143" class="J-stage-100056143 doc-postil"><div><div class="rno-markdown undefined rno-"><p>借助 Angular Service Worker 的这种版本控制行为,应用服务器就可以确保这个 Angular 应用中的这组文件始终保持一致。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056144" class="J-stage-100056144 doc-postil"><div><div class="rno-markdown undefined rno-"><h4>更新检测</h4></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056145" class="J-stage-100056145 doc-postil"><div><div class="rno-markdown undefined rno-"><p>每当用户打开或刷新应用程序时,Angular Service Worker 都会通过查看清单(manifest)文件 “ngsw.json” 的更新来检查该应用程序的更新。 如果它找到了更新,就会自动下载并缓存这个版本,并在下次加载应用程序时提供。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056146" class="J-stage-100056146 doc-postil"><div><div class="rno-markdown undefined rno-"><h3>资源整体性</h3></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056147" class="J-stage-100056147 doc-postil"><div><div class="rno-markdown undefined rno-"><p>长周期缓存的潜在副作用之一就是可能无意中缓存了无效的资源。 在普通的HTTP缓存中,硬刷新或缓存过期限制了缓存这种无效文件导致的负面影响。 而 Service Worker 会忽略这样的约束,事实上会对整个应用程序进行长期缓存。 因此,让 Service Worker 获得正确的内容就显得至关重要。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056148" class="J-stage-100056148 doc-postil"><div><div class="rno-markdown undefined rno-"><p>为了确保资源的整体性,Angular Service Worker 会验证所有带哈希的资源的哈希值。 通常,对于 CLI 应用程序,用户的 <code>src/ngsw-config.json</code>配置文件中会涵盖 <code>dist</code> 目录下的所有内容。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056149" class="J-stage-100056149 doc-postil"><div><div class="rno-markdown undefined rno-"><p>如果某个特定的文件未能通过验证,Angular Service Worker 就会尝试用 “cache-busting” URL 为参数重新获取内容,以消除浏览器或中间缓存的影响。 如果该内容也未能通过验证,则 Service Worker 会认为该应用的整个版本都无效,并停止用它提供服务。 如有必要,Service Worker 会进入安全模式,这些请求将退化为直接访问网络。 如果服务无效、损坏或内容过期的风险很高,则会选择不使用缓存。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056150" class="J-stage-100056150 doc-postil"><div><div class="rno-markdown undefined rno-"><p>导致哈希值不匹配的原因有很多:</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056151" class="J-stage-100056151 doc-postil"><div><div class="rno-markdown undefined rno-"><ul class="ul-level-0"><li>在源服务器和最终用户之间缓存图层可能会提供陈旧的内容。</li><li>非原子化的部署可能会导致 Angular Service Worker 看到部分更新后的内容。</li><li>构建过程中的错误可能会导致更新了资源,却没有更新 <code>ngsw.json</code>。 反之,也可能发生没有更新资源,却更新了 <code>ngsw.json</code> 的情况。</li></ul></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056152" class="J-stage-100056152 doc-postil"><div><div class="rno-markdown undefined rno-"><h4>不带哈希的内容</h4></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056153" class="J-stage-100056153 doc-postil"><div><div class="rno-markdown undefined rno-"><p><code>ngsw.json</code> 清单中唯一带哈希值的资源就是构建清单时 <code>dist</code> 目录中的资源。 而其他资源,特别是从 CDN 加载的资源,其内容在构建时是未知的,或者会比应用程序部署得更频繁。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056154" class="J-stage-100056154 doc-postil"><div><div class="rno-markdown undefined rno-"><p>如果 Angular Service Worker 没有哈希可以验证给定的资源,它仍然会缓存它的内容,但会使用 “重新验证时失效” 的策略来承认HTTP缓存头。 也就是说,当被缓存资源的 HTTP 缓存头指出该资源已过期时,Angular Service Worker 将继续提供内容,并尝试在后台刷新资源。 这样,那些被破坏的非哈希资源留在缓存中的时间就不会超出为它配置的生命周期。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056155" class="J-stage-100056155 doc-postil"><div><div class="rno-markdown undefined rno-"><h3>App 选项卡</h3></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056156" class="J-stage-100056156 doc-postil"><div><div class="rno-markdown undefined rno-"><p>如果应用程序的资源版本突然发生了变化或没有给出警告,就可能会有问题。有关这些问题的描述,请参阅前面的 <a class="" href="/developer/tools/blog-entry?target=https%3A%2F%2Fangular.cn%2Fguide%2Fservice-worker-devops%23versions&objectId=undefined&objectType=" target="_blank" rel="nofollow noopener noreferrer">版本</a> 部分。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056157" class="J-stage-100056157 doc-postil"><div><div class="rno-markdown undefined rno-"><p>Angular Service Worker 会保证:正在运行的应用程序会继续运行和当前应用相同的版本。 而如果在新的 Web 浏览器选项卡中打开了该应用的另一个实例,则会提供该应用的最新版本。 因此,这个新标签可以和原始标签同时运行不同版本的应用。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056158" class="J-stage-100056158 doc-postil"><div><div class="rno-markdown undefined rno-"><p>值得注意的是,这种担保比普通的 Web 部署模型提供的担保还要<strong>更强一点</strong>。 如果没有 Service Worker,则不能保证稍后在这个正在运行的应用中惰性加载的代码 和其初始代码的版本是一样的。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056159" class="J-stage-100056159 doc-postil"><div><div class="rno-markdown undefined rno-"><p>Angular Service Worker 为什么可能会更改运行中的应用的版本有几个有限的原因。 其中一些是因为出错了:</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056160" class="J-stage-100056160 doc-postil"><div><div class="rno-markdown undefined rno-"><ul class="ul-level-0"><li>由于哈希验证失败,当前版本变成了无效的。</li><li>某个无关的错误导致 Service Worker 进入了安全模式,或者说,它被暂时禁用了。</li></ul></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056161" class="J-stage-100056161 doc-postil"><div><div class="rno-markdown undefined rno-"><p>Angular Service Worker 能知道在任何指定的时刻正在使用哪些版本, 并清除那些没有被任何选项卡使用的版本。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056162" class="J-stage-100056162 doc-postil"><div><div class="rno-markdown undefined rno-"><p>另一些可能导致 Angular Service Worker 在运行期间改变版本的因素是一些正常事件:</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056163" class="J-stage-100056163 doc-postil"><div><div class="rno-markdown undefined rno-"><ul class="ul-level-0"><li>页面被重新加载/刷新。</li><li>该页面通过 <a class="" href="/developer/tools/blog-entry?target=https%3A%2F%2Fangular.cn%2Fapi%2Fservice-worker%2FSwUpdate&objectId=undefined&objectType=" target="_blank" rel="nofollow noopener noreferrer"><code>SwUpdate</code></a> 服务请求立即激活这个更新。</li></ul></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056164" class="J-stage-100056164 doc-postil"><div><div class="rno-markdown undefined rno-"><h3>Service Worker 更新</h3></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056165" class="J-stage-100056165 doc-postil"><div><div class="rno-markdown undefined rno-"><p>Angular Service Worker 是一个运行在Web浏览器中的小脚本。 有时,这个 Service Worker 也可能会需要更新,以修复错误和增强特性。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056166" class="J-stage-100056166 doc-postil"><div><div class="rno-markdown undefined rno-"><p>首次打开应用时或在一段非活动时间之后再访问应用程序时,就会下载 Angular Service Worker。 如果 Service Worker 发生了变化,Service Worker 就会在后台进行更新。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056167" class="J-stage-100056167 doc-postil"><div><div class="rno-markdown undefined rno-"><p>Angular Service Worker 的大部分更新对应用程序来说都是透明的 - 旧缓存仍然有效,其内容仍然能正常使用。 但是,在 Angular Service Worker 中可能偶尔会有错误修复或新功能,需要让旧的缓存失效。 这时,应用程序就从会网络上透明地进行刷新。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056168" class="J-stage-100056168 doc-postil"><div><div class="rno-markdown undefined rno-"><h2>调试 Angular Service Worker</h2></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056169" class="J-stage-100056169 doc-postil"><div><div class="rno-markdown undefined rno-"><p>偶尔,可能会需要检查运行中的 Angular Service Worker,以调查问题或确保它在按设计运行。 浏览器提供了用于调试 Service Worker 的内置工具,而且 Angular Service Worker 本身也包含了一些有用的调试功能。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056170" class="J-stage-100056170 doc-postil"><div><div class="rno-markdown undefined rno-"><h3>定位并分析调试信息</h3></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056171" class="J-stage-100056171 doc-postil"><div><div class="rno-markdown undefined rno-"><p>Angular Service Worker 会在虚拟目录 <code>ngsw/</code> 下暴露出调试信息。 目前,它暴露的唯一的 URL 是 <code>ngsw/</code><a class="" href="/developer/tools/blog-entry?target=https%3A%2F%2Fangular.cn%2Fapi%2Fanimations%2Fstate&objectId=undefined&objectType=" target="_blank" rel="nofollow noopener noreferrer"><code>state</code></a>。 下面是这个调试页面中的一段范例内容:</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056172" class="J-stage-100056172 doc-postil markdown-code"><div class="markdown-code-bd"><div><div class="rno-markdown undefined rno-"><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">content_copyNGSW Debug Info: Driver state: NORMAL ((nominal))Latest manifest hash: eea7f5f464f90789b621170af5a569d6be077e5cLast update check: never === Version eea7f5f464f90789b621170af5a569d6be077e5c === Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100f65 === Idle Task Queue ===Last update tick: 1s496uLast update run: neverTask queue: * init post-load (update, cleanup) Debug log:</code></pre></div></div></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div></div><div><div id="stage-100056173" class="J-stage-100056173 doc-postil"><div><div class="rno-markdown undefined rno-"><h4>驱动程序的状态</h4></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056174" class="J-stage-100056174 doc-postil"><div><div class="rno-markdown undefined rno-"><p>第一行表示驱动程序的状态:</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056175" class="J-stage-100056175 doc-postil markdown-code"><div class="markdown-code-bd"><div><div class="rno-markdown undefined rno-"><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">content_copyDriver state: NORMAL ((nominal))</code></pre></div></div></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div></div><div><div id="stage-100056176" class="J-stage-100056176 doc-postil"><div><div class="rno-markdown undefined rno-"><p><code>NORMAL</code> 表示这个 Service Worker 正在正常运行,并且没有处于降级运行的状态。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056177" class="J-stage-100056177 doc-postil"><div><div class="rno-markdown undefined rno-"><p>有两种可能的降级状态:</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056178" class="J-stage-100056178 doc-postil"><div><div class="rno-markdown undefined rno-"><ul class="ul-level-0"><li><code>EXISTING_CLIENTS_ONLY</code>:这个 Service Worker 没有该应用的最新已知版本的干净副本。 较旧的缓存版本可以被安全的使用,所以现有的选项卡将继续使用较旧的版本运行本应用, 但新的应用将从网络上加载。</li><li><code>SAFE_MODE</code>:Service Worker 不能保证使用缓存数据的安全性。 发生了意外错误或所有缓存版本都无效。 这时所有的流量都将从网络提供,尽量少运行 Service Worker 中的代码。</li></ul></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056179" class="J-stage-100056179 doc-postil"><div><div class="rno-markdown undefined rno-"><p>在这两种情况下,后面的括号注解中都会提供导致 Service Worker 进入降级状态的错误信息。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056180" class="J-stage-100056180 doc-postil"><div><div class="rno-markdown undefined rno-"><h4>最新清单的哈希</h4></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056181" class="J-stage-100056181 doc-postil markdown-code"><div class="markdown-code-bd"><div><div class="rno-markdown undefined rno-"><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">content_copyLatest manifest hash: eea7f5f464f90789b621170af5a569d6be077e5c</code></pre></div></div></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div></div><div><div id="stage-100056182" class="J-stage-100056182 doc-postil"><div><div class="rno-markdown undefined rno-"><p>这是 Service Worker 所知道的应用最新版本的 SHA1 哈希值。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056183" class="J-stage-100056183 doc-postil"><div><div class="rno-markdown undefined rno-"><h4>最后一次更新检查</h4></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056184" class="J-stage-100056184 doc-postil markdown-code"><div class="markdown-code-bd"><div><div class="rno-markdown undefined rno-"><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">content_copyLast update check: never</code></pre></div></div></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div></div><div><div id="stage-100056185" class="J-stage-100056185 doc-postil"><div><div class="rno-markdown undefined rno-"><p>这表示 Service Worker 最后一次检查应用程序的新版本或更新的时间。“never” 表示 Service Worker 从未检查过更新。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056186" class="J-stage-100056186 doc-postil"><div><div class="rno-markdown undefined rno-"><p>在这个调试文件范例中,这次更新检查目前是已排期的,如下一节所述。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056187" class="J-stage-100056187 doc-postil"><div><div class="rno-markdown undefined rno-"><h4>版本</h4></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056188" class="J-stage-100056188 doc-postil markdown-code"><div class="markdown-code-bd"><div><div class="rno-markdown undefined rno-"><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">content_copy=== Version eea7f5f464f90789b621170af5a569d6be077e5c === Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100f65</code></pre></div></div></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div></div><div><div id="stage-100056189" class="J-stage-100056189 doc-postil"><div><div class="rno-markdown undefined rno-"><p>在这个例子中,Service Worker 拥有一个版本的应用程序缓存并用它服务于两个不同的选项卡。 请注意,这个版本哈希值是上面列出的“最新清单的哈希”。 它的两个客户运行的都是最新版本。每个客户都用浏览器中 <code>Clients</code> API的 ID 列了出来。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056190" class="J-stage-100056190 doc-postil"><div><div class="rno-markdown undefined rno-"><h4>空闲任务队列</h4></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056191" class="J-stage-100056191 doc-postil markdown-code"><div class="markdown-code-bd"><div><div class="rno-markdown undefined rno-"><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">content_copy=== Idle Task Queue === Last update tick: 1s496u Last update run: never Task queue: * init post-load (update, cleanup)</code></pre></div></div></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div></div><div><div id="stage-100056192" class="J-stage-100056192 doc-postil"><div><div class="rno-markdown undefined rno-"><p>空闲任务队列是 Service Worker 中所有在后台发生的未决任务的队列。 如果这个队列中存在任何任务,则列出它们的描述。 在这个例子中,Service Worker 安排的任务是一个用于更新检查和清除过期缓存的后期初始化操作。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056193" class="J-stage-100056193 doc-postil"><div><div class="rno-markdown undefined rno-"><p>最后的 tick/run 计数器给出了与特定事件发生有关的空闲队列中的时间。 “Last update run” 计数器显示的是上次执行空闲任务的时间。 “Last update tick” 显示的是自上次事件以来可能要处理的队列的时间。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056194" class="J-stage-100056194 doc-postil"><div><div class="rno-markdown undefined rno-"><h4>调试日志</h4></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056195" class="J-stage-100056195 doc-postil markdown-code"><div class="markdown-code-bd"><div><div class="rno-markdown undefined rno-"><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">content_copyDebug log:</code></pre></div></div></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div></div><div><div id="stage-100056196" class="J-stage-100056196 doc-postil"><div><div class="rno-markdown undefined rno-"><p>在 Service Worker 中出现的任何错误都会记录在这里。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056197" class="J-stage-100056197 doc-postil"><div><div class="rno-markdown undefined rno-"><h3>开发者工具</h3></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056198" class="J-stage-100056198 doc-postil"><div><div class="rno-markdown undefined rno-"><p>Chrome 等浏览器提供了能与 Service Worker 交互的开发者工具。 这些工具在使用得当时非常强大,但也要牢记一些事情。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056199" class="J-stage-100056199 doc-postil"><div><div class="rno-markdown undefined rno-"><ul class="ul-level-0"><li>使用开发人员工具时,Service Worker 将继续在后台运行,并且不会重新启动。 这可能会导致开着 Dev Tools 时的行为与用户实际遇到的行为不一样。</li><li>如果你查看缓存存储器的查看器,缓存就会经常过期。右键单击缓存存储器的标题并刷新缓存。</li></ul></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056200" class="J-stage-100056200 doc-postil"><div><div class="rno-markdown undefined rno-"><p>在 Service Worker 页停止并重新启动这个 Service Worker 将会触发一次更新检查。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056201" class="J-stage-100056201 doc-postil"><div><div class="rno-markdown undefined rno-"><h2>Service Worker 的安全性</h2></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056202" class="J-stage-100056202 doc-postil"><div><div class="rno-markdown undefined rno-"><p>像任何复杂的系统一样,错误或损坏的配置可能会导致 Angular Service Worker 以不可预知的方式工作。 虽然它在设计时就尝试将此类问题的影响降至最低,但是,如果管理员需要快速停用 Service Worker, Angular Service Worker 也包含多种故障保护机制。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056203" class="J-stage-100056203 doc-postil"><div><div class="rno-markdown undefined rno-"><h3>故障保护机制</h3></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056204" class="J-stage-100056204 doc-postil"><div><div class="rno-markdown undefined rno-"><p>要停用 Service Worker,请删除或重命名 <code>ngsw-config.json</code> 文件。 当 Service Worker 对 <code>ngsw.json</code> 的请求返回 <code>404</code> 时,Service Worker 就会删除它的所有缓存并注销自己,本质上就是自毁。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056205" class="J-stage-100056205 doc-postil"><div><div class="rno-markdown undefined rno-"><h3>Safety Worker</h3></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056206" class="J-stage-100056206 doc-postil"><div><div class="rno-markdown undefined rno-"><p><code>@angular/service-worker</code> NPM 包中还包含一个小脚本<code>safety-worker.js</code>,当它被加载时就会把它自己从浏览器中注销。 这个脚本可以作为终极武器来摆脱那些已经安装在客户端页面上的不想要的 Service Worker。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056207" class="J-stage-100056207 doc-postil"><div><div class="rno-markdown undefined rno-"><p>要特别注意的是,你不能直接注册这个 Safety Worker,因为具有已缓存状态的旧客户端可能无法看到一个新的、用来安装 另一个 worker 脚本的 <code>index.html</code>。 相反,你必须在想要注销的 Service Worker 脚本的 URL 中提供 <code>safety-worker.js</code> 的内容, 而且必须持续这样做,直到确定所有用户都已成功注销了原有的 Worker。 对大多数网站而言,这意味着你应该永远为旧的 Service Worker URL 提供 这个 Safety Worker。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div><div><div id="stage-100056208" class="J-stage-100056208 doc-postil"><div><div class="rno-markdown undefined rno-"><p>这个脚本可以用来停用 <code>@angular/service-worker</code> 以及任何其它以前在你的站点上提供过的 Service Worker。</p></div></div><div id="J-viewLargeImageBox" class="zoom-mask" style="display:none;width:100%;height:100%"><div class="zoom-close"></div><div class="zoom-wrap"><img/><div class="c-loading"><div class="c-loading-inner"><div class="one"></div><div class="two"></div><div class="three"></div></div></div></div></div></div></div></div><div class="doc-copyright"><p>本文档系腾讯云开发者社区成员共同维护,如有问题请联系 <!-- -->cloudcommunity@tencent.com</p><time class="copyright-time" dateTime="2018-08-28 14:41:36">最后更新于:2018-08-28</time></div></div></div></div><div class="J-page-widgets com-widget-global has-share"><div class="com-widget-shares"><div class="shares-wrap"><span class="com-opt-text share-text">分享</span><ul class="com-share-options"><li><div class="c-bubble-trigger"><a href="javascript:;" class="opt-item"><i class="opt-icon wechat"></i></a><div class="c-bubble c-bubble-right "><div class="c-bubble-inner"><div class="qr-img"></div><p class="qr-txt">分享手册到朋友圈</p></div></div></div></li><li><div class="c-bubble-trigger"><a href="javascript:;" class="opt-item"><i class="opt-icon qq"></i></a><div class="c-bubble c-bubble-right "><div class="c-bubble-inner"><span>分享手册到 QQ</span></div></div></div></li><li><div class="c-bubble-trigger"><a href="javascript:;" class="opt-item"><i class="opt-icon weibo"></i></a><div class="c-bubble c-bubble-right "><div class="c-bubble-inner"><span>分享手册到微博</span></div></div></div></li><li><div class="c-bubble-trigger"><a class="opt-item" href="javascript:;"><i class="opt-icon copy"></i></a><div class="c-bubble c-bubble-right "><div class="c-bubble-inner"><span>复制手册链接到剪贴板</span></div></div></div></li></ul></div><button class="widget-btn collapse-btn"><span class="btn-text">分享</span></button></div><div class="c-bubble-trigger com-widget-qr"><button class="scan-btn" hotrep="community.edge-widget.follow-oa">扫描二维码</button><div class="c-bubble c-bubble-right "><div class="c-bubble-inner"><div class="qr-img"><img src="https://qcloudimg.tencent-cloud.cn/raw/dad61ae6b851b4580d23ffcc4823aef5.png" alt=""/></div><p class="qr-txt">扫码关注腾讯云开发者</p><p class="qr-txt">领取腾讯云代金券</p></div></div></div></div></section></div></div><div id="dialog-root"></div><div id="rno-dialog-root" class="rno-modal-wrap"></div></div><script>window.isServerContext = false; window.isClientContext = true;</script><script>window.$serverTime = 1740573193023; window.$clientTime = 1740573193023;</script><script class="">window.$ua = {"browser":{"name":"IE","version":"7.0","major":"7"},"cpu":{},"device":{},"engine":{},"os":{"name":"Windows","version":"Vista"}};</script><script src="//cloudcache.tencent-cloud.com/qcloud/developer/scripts/release/libs/dom4/1.8.3/dom4.js"></script><script src="https://cloudcache.tencent-cloud.com/qcloud/main/scripts/release/common/vendors/babel/polyfill.6.26.min.js"></script><script src="https://cloudcache.tencent-cloud.com/qcloud/main/scripts/release/common/vendors/react/react.16.8.6.min.js"></script><script src="https://cloudcache.tencent-cloud.com/qcloud/main/scripts/release/common/vendors/react/react-dom.16.8.6.min.js"></script><script src="https://cloudcache.tencent-cloud.com/qcloud/main/scripts/release/common/vendors/jquery-3.2.1.min.js"></script><script src="//cloudcache.tencent-cloud.com/qcloud/developer/scripts/release/base.225e98f95c.js?max_age=31536000" crossorigin="anonymous"></script><script src="//cloudcache.tencent-cloud.com/qcloud/draft-master/dist/draft-master-v2.0.165.d4s2ddo9sb.js?max_age=31536000"></script><script src="https://cloud.tencent.com/qccomponent/login/api.js"></script><script src="//cloudcache.tencent-cloud.com/qcloud/main/scripts/release/common/deps/wechatJsSdk.js?version=1_0_1&max_age=31536000"></script><script src="//cloudcache.tencent-cloud.com/qcloud/developer/scripts/release/common.4ebc077d54.js?max_age=31536000" crossorigin="anonymous"></script><script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.7.2/tcplayer.v4.7.2.min.js"></script><script src="//dscache.tencent-cloud.cn/ecache/qcstat/qcloud/qcloudStatApi.js"></script><script src="https://qccommunity.qcloudimg.com/common/exposure-plugin-4.1.15.min.js"></script><script src="https://qccommunity.qcloudimg.com/community-track/qcloud-community-track.min.js"></script><script src="https://dscache.tencent-cloud.com/sdk/dianshi-sdk/loader/umd/dianshi-sdk-loader.v0.0.18.js"></script><script src="//cloudcache.tencent-cloud.com/qcloud/main/scripts/release/common/vendors/monaco-editor/dev/vs/loader.js"></script><script src="https://cloud.tencent.com/developer/labs/quick/loader"></script><script src="//cloudcache.tencent-cloud.com/qcloud/developer/scripts/release/devdoc/devdoc.7254b75459.js?max_age=31536000" crossorigin="anonymous"></script><script class=""> window.$render({"devdocData":{"title":"生产环境下的 Service Worker","headerTitle":"Angular","focusId":"section.1489572-chapter.18012-doc.1264","activeId":"section.1489572-chapter.18012-doc.1264","ids":["doc.1018","doc.1019","doc.1023","doc.1024","doc.1037","doc.1046","doc.1052","doc.1060","doc.1070","doc.1071","doc.1075","doc.1078","doc.1079","doc.1096","doc.1101","doc.1116","doc.1117","doc.1118","doc.1121","doc.1138","doc.1141","doc.1158","doc.1187","doc.1188","doc.1198","doc.1201","doc.1202","doc.1203","doc.1204","doc.1211","doc.1220","doc.1221","doc.1227","doc.1228","doc.1231","doc.1241","doc.1244","doc.1245","doc.1247","doc.1250","doc.1252","doc.1253","doc.1257","doc.1258","doc.1260","doc.1261","doc.1262","doc.1263","doc.1264","chapter.17995-doc.1264","chapter.17996-doc.1264","chapter.17997-doc.1264","chapter.17998-doc.1264","chapter.17999-doc.1264","chapter.18000-doc.1264","chapter.18001-doc.1264","chapter.18002-doc.1264","chapter.18003-doc.1264","chapter.18004-doc.1264","chapter.18005-doc.1264","chapter.18006-doc.1264","chapter.18008-doc.1264","chapter.18009-doc.1264","chapter.18010-doc.1264","chapter.18011-doc.1264","chapter.18012-doc.1264","section.1489569-chapter.18012-doc.1264","section.1489570-chapter.18012-doc.1264","section.1489571-chapter.18012-doc.1264","section.1489572-chapter.18012-doc.1264","section.1489573-chapter.18012-doc.1264","chapter.18013-doc.1264","chapter.18014-doc.1264","chapter.18015-doc.1264","chapter.18016-doc.1264","chapter.18017-doc.1264","chapter.18018-doc.1264","doc.1265","doc.1266","doc.1267","doc.1268","doc.1270","doc.1271","doc.1272","doc.1273","doc.1278","doc.1279","doc.1281","doc.1282","doc.1292","doc.1293","doc.1309","doc.1320","doc.1322","doc.1324","doc.1325","doc.1326","doc.1407"],"documents":[{"id":1018,"labelId":108,"name":"Bootstrap","nameWithSlug":"Bootstrap 4","type":"bootstrap","home":"https://getbootstrap.com/","sourceCode":"https://github.com/twbs/bootstrap","version":"4","releaseVersion":"4.0.0-beta.2","enable":1,"icon":"https://main.qcloudimg.com/raw/ee986e17811d33bae535a2eb2647ecb1.png","icon2x":"https://main.qcloudimg.com/raw/ee986e17811d33bae535a2eb2647ecb1.png","desc":"Bootstrap 是一套用于 HTML、CSS 和 JS 开发的开源工具集。利用我们提供的 Sass 变量和大量 mixin、响应式栅格系统、可扩展的预制组件、基于 jQuery 的强大的插件系统,能够快速为你的想法开发出原型或者构建整个 app 。","pageViewCount":584315,"tagIds":[10194],"tags":[{"id":10194,"name":"bootstrap"}]},{"id":1019,"labelId":108,"name":"Bootstrap","nameWithSlug":"Bootstrap 3","type":"bootstrap","home":"https://getbootstrap.com/","sourceCode":"https://github.com/twbs/bootstrap","version":"3","releaseVersion":"3.3.7","enable":1,"icon":"https://main.qcloudimg.com/raw/ee986e17811d33bae535a2eb2647ecb1.png","icon2x":"https://main.qcloudimg.com/raw/ee986e17811d33bae535a2eb2647ecb1.png","desc":"Bootstrap 是全球最受欢迎的前端组件库,用于开发响应式布局、移动设备优先的 WEB 项目。","pageViewCount":137576,"tagIds":[10194],"tags":[{"id":10194,"name":"bootstrap"}]},{"id":1023,"labelId":111,"name":"C","nameWithSlug":"C","type":"c","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/bbd212b11fd3c3fab460eccd54327b6f.png","icon2x":"https://main.qcloudimg.com/raw/bbd212b11fd3c3fab460eccd54327b6f.png","desc":"C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。","pageViewCount":971518,"tagIds":[10165],"tags":[{"id":10165,"name":"c 语言"}]},{"id":1024,"labelId":112,"name":"C++","nameWithSlug":"C++","type":"c","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/09d05f338c9c12c5b10679ab3bc5a371.png","icon2x":"https://main.qcloudimg.com/raw/09d05f338c9c12c5b10679ab3bc5a371.png","desc":"C++是C语言的继承,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计,因而C++就适应的问题规模而论,大小由之。","pageViewCount":679746,"tagIds":[10166],"tags":[{"id":10166,"name":"c++"}]},{"id":1037,"labelId":116,"name":"Clojure","nameWithSlug":"Clojure 1.8","type":"clojure","home":"","sourceCode":"","version":"1.8","releaseVersion":"1.8","enable":1,"icon":"https://main.qcloudimg.com/raw/aa9ae1024cdb3dbeba059f46468a8d23.png","icon2x":"https://main.qcloudimg.com/raw/aa9ae1024cdb3dbeba059f46468a8d23.png","desc":"Clojure 是一种运行在 Java 平台上的 Lisp 方言,Lisp 是一种以表达性和功能强大著称的编程语言,但人们通常认为它不太适合应用于一般情况,而 Clojure 的出现彻底改变了这一现状。如今,在任何具备 Java 虚拟机的地方,您都可以利用 Lisp 的强大功能。","pageViewCount":45850,"tagIds":[],"tags":[]},{"id":1046,"labelId":120,"name":"CodeIgniter","nameWithSlug":"Codeigniter 3","type":"sphinx","home":"https://codeigniter.com/","sourceCode":"https://github.com/bcit-ci/CodeIgniter","version":"3","releaseVersion":"3.1.5","enable":1,"icon":"https://main.qcloudimg.com/raw/fdd164a44e34c771dcfdabd27e1138b5.png","icon2x":"https://main.qcloudimg.com/raw/fdd164a44e34c771dcfdabd27e1138b5.png","desc":"CodeIgniter 是一个PHP MVC框架,特点是超轻量级、有数据加密、有灵活URI路由等。对于 PHP 程序员来说,它小巧但功能强大。","pageViewCount":86077,"tagIds":[10615],"tags":[{"id":10615,"name":"codeigniter"}]},{"id":1052,"labelId":124,"name":"CSS","nameWithSlug":"CSS","type":"mdn","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/199d202a2a225d118d8df17338635682.png","icon2x":"https://main.qcloudimg.com/raw/199d202a2a225d118d8df17338635682.png","desc":"层叠样式表( Cascading Style Sheets )是一种用来表现 HTML 或 XML 等文件样式的计算机语言。CSS 不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。","pageViewCount":792712,"tagIds":[10204],"tags":[{"id":10204,"name":"css"}]},{"id":1060,"labelId":128,"name":"Docker","nameWithSlug":"Docker 17","type":"docker","home":"https://docker.com/","sourceCode":"https://github.com/docker/docker","version":"17","releaseVersion":"17.06","enable":1,"icon":"https://main.qcloudimg.com/raw/9f076c75e8aaf04b5a6656982c893ffa.png","icon2x":"https://main.qcloudimg.com/raw/9f076c75e8aaf04b5a6656982c893ffa.png","desc":"Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。","pageViewCount":245157,"tagIds":[10318],"tags":[{"id":10318,"name":"容器镜像服务"}]},{"id":1070,"labelId":133,"name":"Electron","nameWithSlug":"Electron","type":"electron","home":"https://electron.atom.io/","sourceCode":"https://github.com/electron/electron","version":"","releaseVersion":"1.7.9","enable":1,"icon":"https://main.qcloudimg.com/raw/65668d05b89ba9823e6f36a1a6dda6c5.png","icon2x":"https://main.qcloudimg.com/raw/65668d05b89ba9823e6f36a1a6dda6c5.png","desc":"Electron 是一个使用 JavaScript, HTML 和 CSS 等 Web 技术创建原生程序的框架,它负责比较难搞的部分,你只需把精力放在你的应用的核心上即可。","pageViewCount":668637,"tagIds":[10616],"tags":[{"id":10616,"name":"electron"}]},{"id":1071,"labelId":134,"name":"Elixir","nameWithSlug":"Elixir 1.5","type":"elixir","home":"https://elixir-lang.org/","sourceCode":"https://github.com/elixir-lang/elixir","version":"1.5","releaseVersion":"1.5.2","enable":1,"icon":"https://main.qcloudimg.com/raw/21d7d051e70beb27eb0a961cd948a48d.png","icon2x":"https://main.qcloudimg.com/raw/21d7d051e70beb27eb0a961cd948a48d.png","desc":"Elixir 基于 Erlang 虚拟机的函数式、面向并行,是一种较好的编程语言。它以 Erlang 为基础,支持分布式、高容错、实时应用程序的开发。","pageViewCount":106174,"tagIds":[],"tags":[]},{"id":1075,"labelId":136,"name":"Erlang","nameWithSlug":"Erlang 20","type":"erlang","home":"https://www.erlang.org/","sourceCode":"https://github.com/erlang/otp","version":"20","releaseVersion":"20.1","enable":1,"icon":"https://main.qcloudimg.com/raw/20f24c9aaa55d7a1b99ad4a141418cca.png","icon2x":"https://main.qcloudimg.com/raw/20f24c9aaa55d7a1b99ad4a141418cca.png","desc":"Erlang 是一种通用的面向并发的编程语言,可应付大规模开发活动的程序设计语言和运行环境。","pageViewCount":263184,"tagIds":[10177],"tags":[{"id":10177,"name":"erlang"}]},{"id":1078,"labelId":137,"name":"ESLint","nameWithSlug":"Eslint","type":"simple","home":"https://eslint.org/","sourceCode":"https://github.com/eslint/eslint","version":"","releaseVersion":"4.12.0","enable":1,"icon":"https://main.qcloudimg.com/raw/ddd98094fdaabf06c8c60f1e51935860.png","icon2x":"https://main.qcloudimg.com/raw/ddd98094fdaabf06c8c60f1e51935860.png","desc":"ESLint 是一个代码规范和错误检查工具,有以下几个特性。所有东西都是可以插拔的。你可以调用任意的 rule api 或者 formatter api 去打包或者定义 rule or formatter。任意的 rule 都是独立的。没有特定的 coding style,你可以自己配置。","pageViewCount":895697,"tagIds":[10618],"tags":[{"id":10618,"name":"eslint"}]},{"id":1079,"labelId":138,"name":"Express","nameWithSlug":"Express","type":"express","home":"http://expressjs.com/","sourceCode":"https://github.com/strongloop/express/","version":"","releaseVersion":"4.16.1","enable":1,"icon":"https://main.qcloudimg.com/raw/c7e9393951ddb914a7af947a0b76d566.png","icon2x":"https://main.qcloudimg.com/raw/c7e9393951ddb914a7af947a0b76d566.png","desc":"Express 是一个简洁而灵活的 node.js Web 应用框架, 提供一系列强大特性帮助你创建各种 Web 应用。Express 不对 node.js 已有的特性进行二次抽象,只是在它之上扩展了 Web 应用所需的功能。丰富的 HTTP 工具以及来自 Connect 框架的中间件随取随用,创建强健、友好的 API 变得快速又简单。","pageViewCount":142697,"tagIds":[10619],"tags":[{"id":10619,"name":"express"}]},{"id":1096,"labelId":143,"name":"Git","nameWithSlug":"Git","type":"git","home":"https://git-scm.com/","sourceCode":"https://github.com/git/git","version":"","releaseVersion":"2.14.3","enable":1,"icon":"https://main.qcloudimg.com/raw/3b9881490538872ca8acfb9c757d536c.png","icon2x":"https://main.qcloudimg.com/raw/3b9881490538872ca8acfb9c757d536c.png","desc":"Git 是一个分布式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以 GPL 发布。最初目的是为更好地管理 Linux 内核开发而设计。","pageViewCount":608158,"tagIds":[10283],"tags":[{"id":10283,"name":"git"}]},{"id":1101,"labelId":145,"name":"Go","nameWithSlug":"Go","type":"go","home":"https://golang.org/","sourceCode":"https://go.googlesource.com/go","version":"","releaseVersion":"1.9.2","enable":1,"icon":"https://main.qcloudimg.com/raw/d4561739a3aa0ebb492202ed004f6845.png","icon2x":"https://main.qcloudimg.com/raw/d4561739a3aa0ebb492202ed004f6845.png","desc":"Go 是一种编译型语言,它结合了解释型语言的游刃有余,动态类型语言的开发效率,以及静态类型的安全性。它也打算成为现代的,支持网络与多核计算的语言。要满足这些目标,需要解决一些语言上的问题:一个富有表达能力但轻量级的类型系统,并发与垃圾回收机制,严格的依赖规范等等。这些无法通过库或工具解决好,因此Go也就应运而生了。","pageViewCount":1243736,"tagIds":[10174],"tags":[{"id":10174,"name":"go"}]},{"id":1116,"labelId":151,"name":"HTML","nameWithSlug":"HTML","type":"mdn","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/8281f39e6bb68d4ea66a11ae0c35064e.png","icon2x":"https://main.qcloudimg.com/raw/8281f39e6bb68d4ea66a11ae0c35064e.png","desc":"超文本标记语言,它通过标记符号来标记要显示的网页中的各个部分。网页文件本身是一种文本文件,通过在文本文件中添加标记符,可以告诉浏览器如何显示其中的内容(如:文字如何处理,画面如何安排,图片如何显示等)。浏览器按顺序阅读网页文件,然后根据标记符解释和显示其标记的内容,对书写出错的标记将不指出其错误,且不停止其解释执行过程,编制者只能通过显示效果来分析出错原因和出错部位。但需要注意的是,对于不同的浏览器,对同一标记符可能会有不完全相同的解释,因而可能会有不同的显示效果。","pageViewCount":294934,"tagIds":[10205],"tags":[{"id":10205,"name":"html"}]},{"id":1117,"labelId":152,"name":"HTTP","nameWithSlug":"HTTP","type":"mdn","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/553dd829cd43b9b4b0210d27ad1ffea2.png","icon2x":"https://main.qcloudimg.com/raw/553dd829cd43b9b4b0210d27ad1ffea2.png","desc":"超文本传输协议( HTTP,HyperText Transfer Protocol ) 是互联网上应用最为广泛的一种网络协议。所有的 WWW 文件都必须遵守这个标准。","pageViewCount":1125916,"tagIds":[10620],"tags":[{"id":10620,"name":"http"}]},{"id":1118,"labelId":153,"name":"Immutable.js","nameWithSlug":"Immutable 3.8.1","type":"immutable","home":"https://facebook.github.io/immutable-js/","sourceCode":"https://github.com/facebook/immutable-js","version":"","releaseVersion":"3.8.1","enable":1,"icon":"https://main.qcloudimg.com/raw/142bb955cebe43dcd15ec5872825cbdf.png","icon2x":"https://main.qcloudimg.com/raw/142bb955cebe43dcd15ec5872825cbdf.png","desc":"immutable 是 Facebook 开源的一个项目,用于实现 javascript 的数据不可变,解决引用带来的副作用。","pageViewCount":63224,"tagIds":[],"tags":[]},{"id":1121,"labelId":156,"name":"JavaScript","nameWithSlug":"JavaScript","type":"mdn","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/e7765f3f09d213b1e9a69a5d14ee0a18.png","icon2x":"https://main.qcloudimg.com/raw/e7765f3f09d213b1e9a69a5d14ee0a18.png","desc":"JavaScript 是一种高级编程语言,通过解释执行,是一门动态类型,面向对象(基于原型)的解释型语言。它已经由ECMA(欧洲电脑制造商协会)通过 ECMAScript 实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器( Chrome、IE、FireFox、Safari、Opera )支持。JavaScript 是一门基于原型、函数先行的语言,是一门多范式的语言,它支持面向对象编程,命令式编程,以及函数式编程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持 I/O,比如网络、存储和图形等,但这些都可以由它的宿主环境提供支持。","pageViewCount":1000284,"tagIds":[10170],"tags":[{"id":10170,"name":"javascript"}]},{"id":1138,"labelId":167,"name":"lodash","nameWithSlug":"Lodash 4","type":"lodash","home":"https://lodash.com/","sourceCode":"https://github.com/lodash/lodash/","version":"4","releaseVersion":"4.17.4","enable":1,"icon":"https://main.qcloudimg.com/raw/05f5d001238a1ca847c0a29273fb3fdf.png","icon2x":"https://main.qcloudimg.com/raw/05f5d001238a1ca847c0a29273fb3fdf.png","desc":"Lodash 是一个具有一致接口、模块化、高性能等特性的 JavaScript 工具库。","pageViewCount":56054,"tagIds":[10659],"tags":[{"id":10659,"name":"lodash"}]},{"id":1141,"labelId":168,"name":"Lua","nameWithSlug":"Lua 5.3","type":"lua","home":"","sourceCode":"","version":"5.3","releaseVersion":"5.3.4","enable":1,"icon":"https://main.qcloudimg.com/raw/fe45b8dbc693fd39062c172e06206317.png","icon2x":"https://main.qcloudimg.com/raw/fe45b8dbc693fd39062c172e06206317.png","desc":"Lua 是一门轻量而快速的脚本语言,功能在高级动态语言中十分完备,对 C API、嵌入式开发以及线程安全的 VM 的支持,使其非常流行。","pageViewCount":121731,"tagIds":[10175],"tags":[{"id":10175,"name":"lua"}]},{"id":1158,"labelId":178,"name":"nginx","nameWithSlug":"Nginx","type":"nginx","home":"https://nginx.org/","sourceCode":"http://hg.nginx.org/nginx","version":"","releaseVersion":"1.13.6","enable":1,"icon":"https://main.qcloudimg.com/raw/ad00984cfb056d48f054f0b68f0a1ae7.png","icon2x":"https://main.qcloudimg.com/raw/ad00984cfb056d48f054f0b68f0a1ae7.png","desc":"Nginx是一款轻量级的 Web 服务器/反向代理服务器及电子邮件代理服务器,可在 BSD-like 协议下发行。其特点是占有内存少,并发能力强。","pageViewCount":422237,"tagIds":[10315],"tags":[{"id":10315,"name":"nginx"}]},{"id":1187,"labelId":193,"name":"PHP","nameWithSlug":"PHP","type":"php","home":"https://secure.php.net/","sourceCode":"https://git.php.net/?p=php-src.git;a=summary","version":"","releaseVersion":"7.1.12","enable":1,"icon":"https://main.qcloudimg.com/raw/b5d5961eeb147bfc9a935f2fdb76eaa7.png","icon2x":"https://main.qcloudimg.com/raw/b5d5961eeb147bfc9a935f2fdb76eaa7.png","desc":"PHP( Hypertext Preprocessor )是一种通用开源脚本语言。语法吸收了C语言、Java 和 Perl 的特点,利于学习,使用广泛,主要适用于 Web 开发领域。","pageViewCount":461044,"tagIds":[10167],"tags":[{"id":10167,"name":"php"}]},{"id":1188,"labelId":194,"name":"PHPUnit","nameWithSlug":"Phpunit 6","type":"phpunit","home":"https://phpunit.de/","sourceCode":"https://github.com/sebastianbergmann/phpunit","version":"6","releaseVersion":"6.4","enable":1,"icon":"https://main.qcloudimg.com/raw/1e49d3c8513bf0e7752f74c6dc1efeab.png","icon2x":"https://main.qcloudimg.com/raw/1e49d3c8513bf0e7752f74c6dc1efeab.png","desc":"PHPUnit 是一个 xUnit 的体系结构的 PHP 单元测试框架。","pageViewCount":20624,"tagIds":[10623],"tags":[{"id":10623,"name":"phpunit"}]},{"id":1198,"labelId":197,"name":"Python","nameWithSlug":"Python","type":"sphinx","home":"https://www.python.org/","sourceCode":"https://github.com/python/cpython","version":"2.7","releaseVersion":"2.7.13","enable":1,"icon":"https://main.qcloudimg.com/raw/c8a0c79bd0559c257793ad02704dfad4.png","icon2x":"https://main.qcloudimg.com/raw/c8a0c79bd0559c257793ad02704dfad4.png","desc":"Python 是一种面向对象的解释型计算机程序设计语言,由荷兰人 Guido van Rossum 于1989年发明,第一个公开发行版发行于1991年。\nPython 是纯粹的自由软件, 源代码和解释器 CPython 遵循 GPL 协议。Python 语法简洁清晰,特色之一是强制用空白符( white space )作为语句缩进。","pageViewCount":963478,"tagIds":[10169],"tags":[{"id":10169,"name":"python"}]},{"id":1201,"labelId":200,"name":"React","nameWithSlug":"React","type":"simple","home":"https://reactjs.org/","sourceCode":"https://github.com/facebook/react","version":"","releaseVersion":"16.1.0","enable":1,"icon":"https://main.qcloudimg.com/raw/5c5afe657e4cd0cab6601b5bb1ec9272.png","icon2x":"https://main.qcloudimg.com/raw/5c5afe657e4cd0cab6601b5bb1ec9272.png","desc":"React 起源于 Facebook 的内部项目,主要用于构建UI。你可以在React里传递多种类型的参数,如声明代码,帮助你渲染出UI、也可以是静态的HTML DOM元素、也可以传递动态变量、甚至是可交互的应用组件。","pageViewCount":142023,"tagIds":[10198],"tags":[{"id":10198,"name":"react"}]},{"id":1202,"labelId":201,"name":"ReactNative","nameWithSlug":"React native","type":"react_native","home":"https://facebook.github.io/react-native/","sourceCode":"https://github.com/facebook/react-native","version":"","releaseVersion":"0.49","enable":1,"icon":"https://main.qcloudimg.com/raw/5c5afe657e4cd0cab6601b5bb1ec9272.png","icon2x":"https://main.qcloudimg.com/raw/5c5afe657e4cd0cab6601b5bb1ec9272.png","desc":"React Native 是一个 JavaScript 的框架,用来撰写实时的、可原生呈现 iOS 和 Android 的应用。","pageViewCount":121172,"tagIds":[10624],"tags":[{"id":10624,"name":"reactnative"}]},{"id":1203,"labelId":202,"name":"Redis","nameWithSlug":"Redis","type":"redis","home":"https://redis.io/","sourceCode":"https://github.com/antirez/redis","version":"","releaseVersion":"4.0.2","enable":1,"icon":"https://main.qcloudimg.com/raw/23bd9465961c415348ddffae0ee80849.png","icon2x":"https://main.qcloudimg.com/raw/23bd9465961c415348ddffae0ee80849.png","desc":"Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。\n\n它通常被称为数据结构服务器,因为值( value )可以是 字符串( String ), 哈希(Map),列表(list),集合( sets ) 和 有序集合( sorted sets )等类型。","pageViewCount":450233,"tagIds":[10249],"tags":[{"id":10249,"name":"云数据库 Redis®"}]},{"id":1204,"labelId":203,"name":"Redux","nameWithSlug":"Redux","type":"redux","home":"http://redux.js.org/","sourceCode":"https://github.com/reactjs/redux/","version":"","releaseVersion":"3.7.2","enable":1,"icon":"https://main.qcloudimg.com/raw/aac9c7da445187766d7b8974a4478a79.png","icon2x":"https://main.qcloudimg.com/raw/aac9c7da445187766d7b8974a4478a79.png","desc":"Redux由Dan Abramov在2015年创建的科技术语。是受2014年Facebook的Flux架构以及函数式编程语言Elm启发。很快,Redux因其简单易学体积小在短时间内成为最热门的前端架构。","pageViewCount":65824,"tagIds":[10625],"tags":[{"id":10625,"name":"redux"}]},{"id":1211,"labelId":207,"name":"Ruby","nameWithSlug":"Ruby 2.4","type":"rdoc","home":"https://www.ruby-lang.org/","sourceCode":"https://github.com/ruby/ruby","version":"2.4","releaseVersion":"2.4.1","enable":1,"icon":"https://main.qcloudimg.com/raw/b0da03eeec7c332e2b9615934a2d957e.png","icon2x":"https://main.qcloudimg.com/raw/b0da03eeec7c332e2b9615934a2d957e.png","desc":"Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。","pageViewCount":206691,"tagIds":[10172],"tags":[{"id":10172,"name":"ruby"}]},{"id":1220,"labelId":211,"name":"Sass","nameWithSlug":"Sass","type":"yard","home":"http://sass-lang.com/","sourceCode":"https://github.com/sass/sass","version":"","releaseVersion":"3.5.3","enable":1,"icon":"https://main.qcloudimg.com/raw/27f436e35d9b36d4bdd245fd2c7d5a17.png","icon2x":"https://main.qcloudimg.com/raw/27f436e35d9b36d4bdd245fd2c7d5a17.png","desc":"Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库(如 Compass)有助于更好地组织管理样式文件,以及更高效地开发项目。","pageViewCount":44062,"tagIds":[10626],"tags":[{"id":10626,"name":"sass"}]},{"id":1221,"labelId":212,"name":"scikit-image","nameWithSlug":"Scikit image","type":"sphinx","home":"http://scikit-image.org/","sourceCode":"https://github.com/scikit-image/scikit-image","version":"","releaseVersion":"0.13.1","enable":1,"icon":"https://main.qcloudimg.com/raw/32c59e4a9b8eab095c26f394ac149b62.png","icon2x":"https://main.qcloudimg.com/raw/32c59e4a9b8eab095c26f394ac149b62.png","desc":"Scikit-image 是用于图像处理的 Python 包,使用原生的 NumPy 数组作为图像对象。","pageViewCount":328422,"tagIds":[],"tags":[]},{"id":1227,"labelId":215,"name":"Socket.IO","nameWithSlug":"Socket.IO","type":"socketio","home":"http://socket.io/","sourceCode":"https://github.com/socketio/socket.io","version":"","releaseVersion":"1.4.5","enable":1,"icon":"https://main.qcloudimg.com/raw/620ef1d0948e33eab98eef2c0440d145.png","icon2x":"https://main.qcloudimg.com/raw/620ef1d0948e33eab98eef2c0440d145.png","desc":"Socket.IO 是一个面向实时 web 应用的 JavaScript 库。它使得服务器和客户端之间实时双向的通信成为可能。","pageViewCount":62017,"tagIds":[10628],"tags":[{"id":10628,"name":"socket.io"}]},{"id":1228,"labelId":216,"name":"SQLite","nameWithSlug":"Sqlite","type":"sqlite","home":"https://sqlite.org/","sourceCode":"https://www.sqlite.org/src/","version":"","releaseVersion":"3.21.0","enable":1,"icon":"https://main.qcloudimg.com/raw/132cebf267aea6854ab033a1a6e6592e.png","icon2x":"https://main.qcloudimg.com/raw/132cebf267aea6854ab033a1a6e6592e.png","desc":"SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至2015年已经有15个年头,SQLite也迎来了一个版本 SQLite 3已经发布。","pageViewCount":171015,"tagIds":[10246],"tags":[{"id":10246,"name":"sqlite"}]},{"id":1231,"labelId":219,"name":"SVG","nameWithSlug":"SVG","type":"mdn","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/800ff82933f9bd5eee1b18d1955bd476.png","icon2x":"https://main.qcloudimg.com/raw/800ff82933f9bd5eee1b18d1955bd476.png","desc":"可缩放矢量图形是基于可扩展标记语言(标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式。它由万维网联盟制定,是一个开放标准。","pageViewCount":383589,"tagIds":[10622],"tags":[{"id":10622,"name":"svg"}]},{"id":1241,"labelId":222,"name":"TensorFlow","nameWithSlug":"TensorFlow Guide","type":"tensorflow","home":"https://www.tensorflow.org/","sourceCode":"https://github.com/tensorflow/tensorflow","version":"Guide","releaseVersion":"1.4","enable":1,"icon":"https://main.qcloudimg.com/raw/efd0b60404a54763ae096c4176e9d2e6.png","icon2x":"https://main.qcloudimg.com/raw/efd0b60404a54763ae096c4176e9d2e6.png","desc":"TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流图的一端流动到另一端计算过程。TensorFlow是将复杂的数据结构传输至人工智能神经网中进行分析和处理过程的系统。","pageViewCount":147789,"tagIds":[10150],"tags":[{"id":10150,"name":"tensorflow"}]},{"id":1244,"labelId":224,"name":"TypeScript","nameWithSlug":"Typescript","type":"typescript","home":"https://www.typescriptlang.org","sourceCode":"https://github.com/Microsoft/TypeScript","version":"","releaseVersion":"2.6.0","enable":1,"icon":"https://main.qcloudimg.com/raw/1381358584ecd0a15becada8f8e2017b.png","icon2x":"https://main.qcloudimg.com/raw/1381358584ecd0a15becada8f8e2017b.png","desc":"TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。","pageViewCount":168347,"tagIds":[10213],"tags":[{"id":10213,"name":"typescript"}]},{"id":1245,"labelId":225,"name":"Underscore.js","nameWithSlug":"Underscore","type":"underscore","home":"","sourceCode":"","version":"","releaseVersion":"1.8.3","enable":1,"icon":"https://main.qcloudimg.com/raw/6f46eb25195d526f06700a3aa8cc3485.png","icon2x":"https://main.qcloudimg.com/raw/6f46eb25195d526f06700a3aa8cc3485.png","desc":"Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象。","pageViewCount":19966,"tagIds":[10632],"tags":[{"id":10632,"name":"underscore"}]},{"id":1247,"labelId":227,"name":"Vue.js","nameWithSlug":"Vue 2","type":"vue","home":"https://vuejs.org/","sourceCode":"https://github.com/vuejs/vue","version":"2","releaseVersion":"2.5.2","enable":1,"icon":"https://main.qcloudimg.com/raw/dcc267ca87a633f395baa593a3dd899d.png","icon2x":"https://main.qcloudimg.com/raw/dcc267ca87a633f395baa593a3dd899d.png","desc":"Vue.js 是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。","pageViewCount":420871,"tagIds":[10197],"tags":[{"id":10197,"name":"vue.js"}]},{"id":1250,"labelId":229,"name":"webpack","nameWithSlug":"Webpack","type":"webpack","home":"https://webpack.js.org/","sourceCode":"https://github.com/webpack/webpack","version":"","releaseVersion":"3.8.1","enable":1,"icon":"https://main.qcloudimg.com/raw/5f8c9e286f7ca994db07ef8803bba9e8.png","icon2x":"https://main.qcloudimg.com/raw/5f8c9e286f7ca994db07ef8803bba9e8.png","desc":"webpack 是一个模块打包器。webpack 处理带有依赖关系的模块,生成一系列表示这些模块的静态资源。","pageViewCount":338898,"tagIds":[10629],"tags":[{"id":10629,"name":"webpack"}]},{"id":1252,"labelId":230,"name":"XSLT & XPath","nameWithSlug":"Xslt & Xpath","type":"mdn","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/8c05850b2e13a75546f6c8a1fb7648ef.png","icon2x":"https://main.qcloudimg.com/raw/8c05850b2e13a75546f6c8a1fb7648ef.png","desc":"XSLT 是扩展样式表转换语言 的外语缩写,这是一种对 XML(标准通用标记语言的子集)文档进行转化的语言,XSLT 中的 T 代表英语中的“转换”(Transformation)。它是 XSL(eXtensible Stylesheet Language)规范的一部分","pageViewCount":57574,"tagIds":[10633],"tags":[{"id":10633,"name":"xslt & xpath"}]},{"id":1253,"labelId":231,"name":"Yarn","nameWithSlug":"Yarn","type":"yarn","home":"https://yarnpkg.com/","sourceCode":"https://github.com/yarnpkg/yarn","version":"","releaseVersion":"1.3.2","enable":1,"icon":"https://main.qcloudimg.com/raw/6783dcd935b3976111d85c408df944d7.png","icon2x":"https://main.qcloudimg.com/raw/6783dcd935b3976111d85c408df944d7.png","desc":"Apache Hadoop YARN (Yet Another Resource Negotiator,另一种资源协调者)是一种新的 Hadoop 资源管理器,它是一个通用资源管理系统,可为上层应用提供统一的资源管理和调度,它的引入为集群在利用率、资源统一管理和数据共享等方面带来了巨大好处。","pageViewCount":181133,"tagIds":[10631],"tags":[{"id":10631,"name":"yarn"}]},{"id":1257,"labelId":0,"name":"RxJS 5","nameWithSlug":"RxJS 5","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/3834d5e3369eba9f19b64bac1d89d194.png","icon2x":"https://main.qcloudimg.com/raw/3834d5e3369eba9f19b64bac1d89d194.png","desc":"RxJS 是一个库,它通过使用 observable 序列来编写异步和基于事件的程序。它提供了一个核心类型 Observable,附属类型 (Observer、 Schedulers、 Subjects) 和受 [Array#extras] 启发的操作符 (map、filter、reduce、every, 等等),这些数组操作符可以把异步事件作为集合来处理。","pageViewCount":82353,"tagIds":[10642],"tags":[{"id":10642,"name":"rxjs"}]},{"id":1258,"labelId":0,"name":"Rollup","nameWithSlug":"Rollup.js","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/4ae7011e33bd5fc4e6255a5525bf6cc1.png","icon2x":"https://main.qcloudimg.com/raw/4ae7011e33bd5fc4e6255a5525bf6cc1.png","desc":"Rollup 是一个 JavaScript 模块打包工具,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。","pageViewCount":22151,"tagIds":[10643],"tags":[{"id":10643,"name":"rollup.js"}]},{"id":1260,"labelId":0,"name":"Babel","nameWithSlug":"Babel ","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/091b6c7bc470a4553017a47fdc9c5b5a.png","icon2x":"https://main.qcloudimg.com/raw/091b6c7bc470a4553017a47fdc9c5b5a.png","desc":"Babel 是一个通用的多用途 JavaScript 编译器,通过 Babel 你可以使用(并创建)下一代的 JavaScript。","pageViewCount":114969,"tagIds":[10644],"tags":[{"id":10644,"name":"babel.js"}]},{"id":1261,"labelId":0,"name":"Parcel","nameWithSlug":"Parcel","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/60b3c2cd3a70a8aae4358a2c5e3821e3.png","icon2x":"https://main.qcloudimg.com/raw/60b3c2cd3a70a8aae4358a2c5e3821e3.png","desc":"Parcel 是一个网络应用打包工具,适用于经验不同的开发者。它利用多核处理提供了极快的速度,并且不需要任何配置。","pageViewCount":18408,"tagIds":[10653],"tags":[{"id":10653,"name":"parcel"}]},{"id":1262,"labelId":0,"name":"MobX","nameWithSlug":"MobX","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/b81b145550929479699e54c3b1f207bb.png","icon2x":"https://main.qcloudimg.com/raw/b81b145550929479699e54c3b1f207bb.png","desc":"MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展。","pageViewCount":114127,"tagIds":[10654],"tags":[{"id":10654,"name":"mobx"}]},{"id":1263,"labelId":0,"name":"koa","nameWithSlug":"Koa","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/6e14af5a5cc799e479a21c795e0bbfa4.png","icon2x":"https://main.qcloudimg.com/raw/6e14af5a5cc799e479a21c795e0bbfa4.png","desc":"Koa (koajs) 是一个新的 web 框架,由 Express 幕后的原班人马打造,致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。","pageViewCount":55552,"tagIds":[10655],"tags":[{"id":10655,"name":"koa"}]},{"id":1264,"labelId":0,"name":"Angular","nameWithSlug":"Angular","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/e8c49341c863b1adcc85af2b6a2069db.png","icon2x":"https://main.qcloudimg.com/raw/e8c49341c863b1adcc85af2b6a2069db.png","desc":"Angular 是一个开发平台。它能帮你更轻松的构建 Web 应用。Angular 集声明式模板、依赖注入、端到端工具和一些最佳实践于一身,为你解决开发方面的各种挑战。","pageViewCount":260774,"tagIds":[10196],"tags":[{"id":10196,"name":"angularjs"}],"expand":true},{"id":1265,"labelId":0,"name":"gulp","nameWithSlug":"Gulp","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/caf6b28113950ce4340e06359f49a504.png","icon2x":"https://main.qcloudimg.com/raw/caf6b28113950ce4340e06359f49a504.png","desc":"Gulp.js 是一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务。","pageViewCount":37616,"tagIds":[10656],"tags":[{"id":10656,"name":"gulp"}]},{"id":1266,"labelId":0,"name":"Grunt","nameWithSlug":"Grunt","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/420c7fbb54021275fd17d9c5d1ea2b85.png","icon2x":"https://main.qcloudimg.com/raw/420c7fbb54021275fd17d9c5d1ea2b85.png","desc":"Grunt 是基于 Node.js 的项目构建工具,它可以自动运行你所设定的任务。Grunt 拥有数量庞大的插件,几乎任何你所要做的事情都可以用 Grunt 实现。","pageViewCount":21105,"tagIds":[10657],"tags":[{"id":10657,"name":"grunt"}]},{"id":1267,"labelId":0,"name":"Stylelint","nameWithSlug":"Stylelint","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/0689f2d1c5100b25abee6b0dadfbb486.png","icon2x":"https://main.qcloudimg.com/raw/0689f2d1c5100b25abee6b0dadfbb486.png","desc":"Stylelint 是一个基于 Javascript 的代码审查工具,它易于扩展,支持最新的 CSS 语法,也理解类似 CSS 的语法。","pageViewCount":90114,"tagIds":[10658],"tags":[{"id":10658,"name":"stylelint"}]},{"id":1268,"labelId":0,"name":"Standard JS","nameWithSlug":"Standard JS ","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/5ef71d8183d09dd0f1dac7c518f3a3cb.png","icon2x":"https://main.qcloudimg.com/raw/5ef71d8183d09dd0f1dac7c518f3a3cb.png","desc":"JavaScript 代码规范,自带 linter & 代码自动修正,可以帮助你(及你的团队)节省大量时间","pageViewCount":95781,"tagIds":[10170],"tags":[{"id":10170,"name":"javascript"}]},{"id":1270,"labelId":0,"name":"Element UI","nameWithSlug":" Element UI","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/c1e4f4dbc9f8d54cbbdb94da8a38d6f9.svg","icon2x":"https://main.qcloudimg.com/raw/c1e4f4dbc9f8d54cbbdb94da8a38d6f9.svg","desc":"Element UI 是一套采用 Vue 2.0 作为基础框架实现的组件库,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的组件库,提供了配套设计资源,帮助网站快速成型","pageViewCount":7759542,"tagIds":[10829],"tags":[{"id":10829,"name":"element ui"}]},{"id":1271,"labelId":0,"name":"iView UI","nameWithSlug":"iView UI","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/2fe503f4c2b328ff294afcee60501005.svg","icon2x":"https://main.qcloudimg.com/raw/2fe503f4c2b328ff294afcee60501005.svg","desc":"iView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品","pageViewCount":1151756,"tagIds":[10830],"tags":[{"id":10830,"name":"iview ui"}]},{"id":1272,"labelId":0,"name":"Lavas","nameWithSlug":"Lavas","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/0fa336e3bd3b9a45bc0d5f1db0fcda38.svg","icon2x":"https://main.qcloudimg.com/raw/0fa336e3bd3b9a45bc0d5f1db0fcda38.svg","desc":"Lavas 是一套基于 Vue 的 PWA 解决方案,能够帮助开发者快速搭建 PWA 应用,解决接入 PWA 的各种问题,对提升用户体验,用户留存率等有明显提升,且开发者无须过多的关注 PWA 开发本身。","pageViewCount":138350,"tagIds":[10832],"tags":[{"id":10832,"name":"lavas"}]},{"id":1273,"labelId":0,"name":"Mint UI","nameWithSlug":"Mint UI","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/1100f38ef1f4ea051d57e26c2466db85.svg","icon2x":"https://main.qcloudimg.com/raw/1100f38ef1f4ea051d57e26c2466db85.svg","desc":"基于 Vue.js 的移动端组件库","pageViewCount":1211925,"tagIds":[10842],"tags":[{"id":10842,"name":"mint ui"}]},{"id":1278,"labelId":0,"name":"PostCSS","nameWithSlug":"PostCSS ","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/729abeb836afaf86d93dab798353d82c.svg","icon2x":"https://main.qcloudimg.com/raw/729abeb836afaf86d93dab798353d82c.svg","desc":"PostCSS 是一个利用 JS 插件来对 CSS 进行转换的工具","pageViewCount":131765,"tagIds":[10843],"tags":[{"id":10843,"name":"postcss"}]},{"id":1279,"labelId":0,"name":"ThinkJS","nameWithSlug":"ThinkJS","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/5aa23e8c0965e282fa43c5712dd0d935.svg","icon2x":"https://main.qcloudimg.com/raw/5aa23e8c0965e282fa43c5712dd0d935.svg","desc":"ThinkJS 是一款面向未来开发的 Node.js 框架,整合了大量的项目最佳实践,让企业级开发变得简单、高效","pageViewCount":121671,"tagIds":[10841],"tags":[{"id":10841,"name":"thinkjs"}]},{"id":1281,"labelId":0,"name":"Nest","nameWithSlug":"Nest","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/0997355bc7bde23cf1faccc32b5de571.png","icon2x":"https://main.qcloudimg.com/raw/0997355bc7bde23cf1faccc32b5de571.png","desc":"Nest 是一个用于构建高效,可扩展的 Node.js 服务器端应用程序的框架","pageViewCount":257632,"tagIds":[10844],"tags":[{"id":10844,"name":"nest"}]},{"id":1282,"labelId":0,"name":"npm","nameWithSlug":"npm","type":"","home":"","sourceCode":"","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/68cb6e2d8b03494a4913c27fa0835c7e.svg","icon2x":"https://main.qcloudimg.com/raw/68cb6e2d8b03494a4913c27fa0835c7e.svg","desc":"npm 是 JavaScript 的包管理器和世界上最大的软件注册表","pageViewCount":372024,"tagIds":[10728],"tags":[{"id":10728,"name":"npm"}]},{"id":1292,"labelId":0,"name":"Node.js教程","nameWithSlug":"Node.js教程","type":"","home":"https://nodejs.org/en/","sourceCode":"https://github.com/nodejs/node","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/3199368d55b8dfc8617e2a562a50b993.png","icon2x":"https://main.qcloudimg.com/raw/3199368d55b8dfc8617e2a562a50b993.png","desc":"Node.js是一个基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动,非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。","pageViewCount":209479,"tagIds":[10200],"tags":[{"id":10200,"name":"node.js"}]},{"id":1293,"labelId":0,"name":"JSON教程","nameWithSlug":"JSON教程","type":"","home":"http://www.json.org/json-zh.htmljson","sourceCode":"https://github.com/topics/json","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/ab7df92584b878ceb24ae515ce81f172.png","icon2x":"https://main.qcloudimg.com/raw/ab7df92584b878ceb24ae515ce81f172.png","desc":"JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等),易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。从Web API和服务端编程语言到NoSQL数据库和客户端框架,都有JSON的身影,在不同平台间传递数据方面,JSON已成为XML强有力的替代者。","pageViewCount":199987,"tagIds":[10207],"tags":[{"id":10207,"name":"json"}]},{"id":1309,"labelId":0,"name":"Groovy教程","nameWithSlug":"Groovy教程","type":"","home":"http://www.groovy-lang.org/","sourceCode":"https://github.com/apache/groovy","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/9c00f5630270408b01e6442cc74891e2.png","icon2x":"https://main.qcloudimg.com/raw/9c00f5630270408b01e6442cc74891e2.png","desc":"Groovy是JVM的一种替代语言,使用方式基本与使用 Java代码的方式相同,该语言特别适合与Spring的动态语言支持一起使用,设计时充分考虑了Java集成。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性,是一种成熟的面向对象编程语言。","pageViewCount":127505,"tagIds":[],"tags":[]},{"id":1320,"labelId":0,"name":"vb.net教程","nameWithSlug":"vb.net教程","type":"","home":"https://msdn.microsoft.com/en-us/library/aa187916.aspx","sourceCode":"https://github.com/mono/monodevelop/pull/8581","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/bf0e56f8f95181d143733f3e698b09e0.png","icon2x":"https://main.qcloudimg.com/raw/bf0e56f8f95181d143733f3e698b09e0.png","desc":"VB.Net是一种简单,现代,面向对象的计算机编程语言。它产生高效的程序。可以在各种计算机平台上进行编译。VB.Net强大的编程功能VB.Net有许多强大的编程功能,使世界各地的程序员都很喜欢使用它。 ","pageViewCount":89502,"tagIds":[],"tags":[]},{"id":1322,"labelId":0,"name":"Storm 入门教程","nameWithSlug":"Storm入门教程","type":"","home":"http://storm.apache.org/","sourceCode":"https://github.com/apache/storm","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/258beb187a7bd054e9660415c5a4cb70.png","icon2x":"https://main.qcloudimg.com/raw/258beb187a7bd054e9660415c5a4cb70.png","desc":"Storm 是一个分布式的,可靠的,容错的数据流处理系统。它会把工作任务委托给不同类型的组件,每个组件负责处理一项简单特定的任务。Storm 集群的输入流由一个被称作 spout 的组件管理,spout 把数据传递给 bolt, bolt 要么把数据保存到某种存储器,要么把数据传递给其它的 bolt。一个 Storm 集群就是在一连串的 bolt 之间转换 spout 传过来的数据。","pageViewCount":38733,"tagIds":[],"tags":[]},{"id":1324,"labelId":0,"name":"Hibernate 教程","nameWithSlug":"Hibernate 教程","type":"","home":"http://hibernate.org/","sourceCode":"https://github.com/hibernate/","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/3203d6a0f9ed96d2672fde70acbd45a4.png","icon2x":"https://main.qcloudimg.com/raw/3203d6a0f9ed96d2672fde70acbd45a4.png","desc":"Bootstrap 是一套用于 HTML、CSS 和 JS 开发的开源工具集。利用我们提供的 Sass 变量和大量 mixin、响应式栅格系统、可扩展的预制组件、基于 jQuery 的强大的插件系统,能够快速为你的想法开发出原型或者构建整个 app 。","pageViewCount":41685,"tagIds":[],"tags":[]},{"id":1325,"labelId":0,"name":"Slick 教程","nameWithSlug":"Slick教程","type":"","home":"http://slick.lightbend.com/","sourceCode":"https://github.com/slick/slick","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/a8185507ff066fd9b56db06acf411ef1.png","icon2x":"https://main.qcloudimg.com/raw/a8185507ff066fd9b56db06acf411ef1.png","desc":"SLICK是Scala的一个现代数据库查询和访问库。它允许您像使用Scala集合一样处理存储数据,同时让您完全控制数据库访问时间和传输的数据。SLICK提供了一个可扩展的查询编译器,可以为不同的后端生成代码。","pageViewCount":17772,"tagIds":[],"tags":[]},{"id":1326,"labelId":0,"name":"MongoDB教程","nameWithSlug":"MongoDB教程","type":"","home":"https://www.mongodb.com/","sourceCode":"https://github.com/mongodb","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/38302d41331de90d0de1303851193a0e.png","icon2x":"https://main.qcloudimg.com/raw/38302d41331de90d0de1303851193a0e.png","desc":"MongoDB 是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。特点是高性能、易部署、易使用,存储数据非常方便。MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的产品。","pageViewCount":90224,"tagIds":[10537],"tags":[{"id":10537,"name":"mongodb"}]},{"id":1407,"labelId":0,"name":"Yii 2.0 权威指南","nameWithSlug":"Yii 2.0","type":"","home":"http://www.yiiframework.com/","sourceCode":"https://github.com/yiisoft/yii2","version":"","releaseVersion":"","enable":1,"icon":"https://main.qcloudimg.com/raw/d81c32ff85716189b65c20405d555962.png","icon2x":"https://main.qcloudimg.com/raw/d81c32ff85716189b65c20405d555962.png","desc":"Yii(Yii Framework)是一个高性能的PHP5的web应用程序开发框架。通过一个简单的命令行工具 “yiic”可以快速创建一个web应用程序的代码框架,开发者可以在生成的代码框架基础上添加业务逻辑,以帮助开发者快速完成应用程序的开发。","pageViewCount":126901,"tagIds":[10886],"tags":[{"id":10886,"name":"yii"}]}],"chapterMap":{"1264":[{"id":17995,"documentId":1264,"name":"快速上手 | quick start ","enName":"快速上手 | quick start ","rank":0,"createTime":1535358024,"updateTime":0},{"id":17996,"documentId":1264,"name":" 教程 | Tutorial","enName":" 教程 | Tutorial","rank":0,"createTime":1535358101,"updateTime":0},{"id":17997,"documentId":1264,"name":"架构 ","enName":"架构 ","rank":0,"createTime":1535358442,"updateTime":0},{"id":17998,"documentId":1264,"name":"组件与模板","enName":"组件与模板","rank":0,"createTime":1535358667,"updateTime":0},{"id":17999,"documentId":1264,"name":"表单 ","enName":"表单 ","rank":0,"createTime":1535422250,"updateTime":0},{"id":18000,"documentId":1264,"name":"可观察对象与RxJS ","enName":"可观察对象与RxJS ","rank":0,"createTime":1535422487,"updateTime":0},{"id":18001,"documentId":1264,"name":"引导启动","enName":"引导启动","rank":0,"createTime":1535422718,"updateTime":0},{"id":18002,"documentId":1264,"name":"Angular 模块","enName":"Angular 模块","rank":0,"createTime":1535422748,"updateTime":0},{"id":18003,"documentId":1264,"name":"依赖注入","enName":"依赖注入","rank":0,"createTime":1535423279,"updateTime":0},{"id":18004,"documentId":1264,"name":"HttpClient","enName":"HttpClient","rank":0,"createTime":1535437189,"updateTime":0},{"id":18005,"documentId":1264,"name":"路由与导航","enName":"路由与导航","rank":0,"createTime":1535437485,"updateTime":0},{"id":18006,"documentId":1264,"name":"测试","enName":"测试","rank":0,"createTime":1535437658,"updateTime":0},{"id":18008,"documentId":1264,"name":"国际化","enName":"国际化","rank":0,"createTime":1535437972,"updateTime":0},{"id":18009,"documentId":1264,"name":"语言服务","enName":"语言服务","rank":0,"createTime":1535438023,"updateTime":0},{"id":18010,"documentId":1264,"name":"安全","enName":"安全","rank":0,"createTime":1535438060,"updateTime":0},{"id":18011,"documentId":1264,"name":"环境准备与部署","enName":"环境准备与部署","rank":0,"createTime":1535438100,"updateTime":0},{"id":18012,"documentId":1264,"name":"Service Worker","enName":"Service Worker","rank":0,"createTime":1535438365,"updateTime":0,"expand":true},{"id":18013,"documentId":1264,"name":"保持最新 ","enName":"保持最新 ","rank":0,"createTime":1535438542,"updateTime":0},{"id":18014,"documentId":1264,"name":"从 AngularJS 升级","enName":"从 AngularJS 升级","rank":0,"createTime":1535439045,"updateTime":0},{"id":18015,"documentId":1264,"name":"服务端渲染","enName":"服务端渲染","rank":0,"createTime":1535439171,"updateTime":0},{"id":18016,"documentId":1264,"name":"Visual Studio 2015 快速上手","enName":"Visual Studio 2015 快速上手","rank":0,"createTime":1535439211,"updateTime":0},{"id":18017,"documentId":1264,"name":"风格指南","enName":"风格指南","rank":0,"createTime":1535439262,"updateTime":0},{"id":18018,"documentId":1264,"name":"词汇表","enName":"词汇表","rank":0,"createTime":1535439299,"updateTime":0}]},"sectionMap":{"18012":[{"id":1489569,"chapterId":18012,"documentId":1264,"name":"简介","enName":"简介","rank":0,"isAnchor":false,"createTime":1535438389,"updateTime":0},{"id":1489570,"chapterId":18012,"documentId":1264,"name":"快速起步","enName":"快速起步","rank":0,"isAnchor":false,"createTime":1535438413,"updateTime":0},{"id":1489571,"chapterId":18012,"documentId":1264,"name":"与 Service Worker 通讯","enName":"与 Service Worker 通讯","rank":0,"isAnchor":false,"createTime":1535438460,"updateTime":0},{"id":1489572,"chapterId":18012,"documentId":1264,"name":"生产环境下的 Service Worker","enName":"生产环境下的 Service Worker","rank":0,"isAnchor":false,"createTime":1535438496,"updateTime":0},{"id":1489573,"chapterId":18012,"documentId":1264,"name":"Service Worker 配置","enName":"Service Worker 配置","rank":0,"isAnchor":false,"createTime":1535438524,"updateTime":0}]},"documentId":1264,"chapterId":18012,"sectionId":1489572,"articleMap":{"1489572":[{"id":100056130,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":0,"content":{"blocks":[{"key":"ecrjg","text":"生产环境下的 Service Worker","type":"header-one","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056131,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":1,"content":{"blocks":[{"key":"5u4q1","text":"本页讲的是如何使用 Angular Service Worker 发布和支持生产环境下的应用。 它解释了 Angular Service Worker 如何满足大规模生产环境的需求、Service Worker 在多种条件下有哪些行为以及有哪些可用的资源和故障保护机制。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056132,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":2,"content":{"blocks":[{"key":"e9fa6","text":"前提条件","type":"header-four","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056133,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":3,"content":{"blocks":[{"key":"abcli","text":"对下列知识有基本的了解:","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056134,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":4,"content":{"blocks":[{"key":"4svbo","text":"与 Service Worker 通讯.","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[{"offset":0,"length":19,"key":0}],"data":[]}],"entityMap":[{"type":"LINK","mutability":"MUTABLE","data":{"url":"https://angular.cn/guide/service-worker-communications"}}]}},{"id":100056135,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":5,"content":{"blocks":[{"key":"bovjr","text":"----","type":"atomic","depth":0,"inlineStyleRanges":[],"entityRanges":[{"offset":0,"length":4,"key":1}],"data":[]}],"entityMap":{"1":{"type":"HR","mutability":"IMMUTABLE","data":[]}}}},{"id":100056136,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":6,"content":{"blocks":[{"key":"4gpk9","text":"Service Worker 与应用资源的缓存","type":"header-two","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056137,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":7,"content":{"blocks":[{"key":"1oau6","text":"从概念上说,你可以把 Angular Service Worker 想象成一个转发式缓存或装在最终用户浏览器中的 CDN 边缘。 Service Worker 的工作是从本地缓存中满足 Angular 应用对资源或数据的请求,而不用等待网络。 和所有缓存一样,它有一些规则来决定内容该如何过期或更新。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056138,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":8,"content":{"blocks":[{"key":"4enkp","text":"应用的版本","type":"header-three","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056139,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":9,"content":{"blocks":[{"key":"59j8l","text":"在 Angular Service Worker 的语境下,“版本”是指用来表示 Angular 应用的某一次构建成果的一组资源。 当应用的一个新的构建发布时,Service Worker 就把它看做此应用的一个新版本。 就算只修改了一个文件,也同样如此。 在任何一个给定的时间,Service Worker 可能会在它的缓存中拥有此应用的多个版本,这几个版本也都能用于提供服务。 要了解更多,参见稍后的 App 选项卡。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[{"offset":203,"length":7,"key":2}],"data":[]}],"entityMap":{"2":{"type":"LINK","mutability":"MUTABLE","data":{"url":"https://angular.cn/guide/service-worker-devops#tabs"}}}}},{"id":100056140,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":10,"content":{"blocks":[{"key":"99ksm","text":"要保持应用的整体性,Angular Service Worker 会用所有的文件共同组成一个版本。 组成版本的这些文件通常包括 HTML、JS 和 CSS 文件。把这些文件分成一组是至关重要的,因为它们会互相引用,并且依赖于一些特定内容。 比如,index.html 文件可能有个引用 bundle.js 的 \u003Cscript\u003E标签,它可能会试图从这个脚本中调用一个 startApp() 函数。 任何时候,只要这个版本的 index.html 被提供了,与它对应的 bundle.js 也必须同时提供。 这种情况下,使用调用了 startApp() 的老的 index.html并同时使用定义了 runApp() 的新 bundle 就是无效的。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":123,"length":10,"style":"CODE"},{"offset":143,"length":9,"style":"CODE"},{"offset":155,"length":8,"style":"CODE"},{"offset":183,"length":10,"style":"CODE"},{"offset":211,"length":10,"style":"CODE"},{"offset":233,"length":9,"style":"CODE"},{"offset":264,"length":10,"style":"CODE"},{"offset":279,"length":10,"style":"CODE"},{"offset":298,"length":8,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056141,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":11,"content":{"blocks":[{"key":"339jr","text":"当使用惰性加载模块时,文件的整体性就显得格外重要。 某个 JS 包可能引用很多惰性块,而这些惰性块的文件名在应用的每次特定的构建中都是唯一的。 如果运行应用的 X 版本视图加载一个惰性块,但该块的服务器已经升级到了 X + 1版本,这次惰性加载操作就会失败。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":80,"length":1,"style":"CODE"},{"offset":108,"length":5,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056142,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":12,"content":{"blocks":[{"key":"a6bhj","text":"本应用的版本标识符由其所有资源的内容决定,如果它们中的任何一个发生了变化,则版本标识符也随之改变。 实际上,版本是由 ngsw.json 文件的内容决定的,包含了所有已知内容的哈希值。 如果任何一个被缓存的文件发生了变化,则该文件的哈希也将在ngsw.json中随之变化,从而导致 Angular Service Worker 将这个活动文件的集合视为一个新版本。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":59,"length":9,"style":"CODE"},{"offset":121,"length":9,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056143,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":13,"content":{"blocks":[{"key":"f0ldc","text":"借助 Angular Service Worker 的这种版本控制行为,应用服务器就可以确保这个 Angular 应用中的这组文件始终保持一致。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056144,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":14,"content":{"blocks":[{"key":"2b6h9","text":"更新检测","type":"header-four","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056145,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":15,"content":{"blocks":[{"key":"9pden","text":"每当用户打开或刷新应用程序时,Angular Service Worker 都会通过查看清单(manifest)文件 “ngsw.json” 的更新来检查该应用程序的更新。 如果它找到了更新,就会自动下载并缓存这个版本,并在下次加载应用程序时提供。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056146,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":16,"content":{"blocks":[{"key":"81v19","text":"资源整体性","type":"header-three","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056147,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":17,"content":{"blocks":[{"key":"bgsqq","text":"长周期缓存的潜在副作用之一就是可能无意中缓存了无效的资源。 在普通的HTTP缓存中,硬刷新或缓存过期限制了缓存这种无效文件导致的负面影响。 而 Service Worker 会忽略这样的约束,事实上会对整个应用程序进行长期缓存。 因此,让 Service Worker 获得正确的内容就显得至关重要。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056148,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":18,"content":{"blocks":[{"key":"6k5m9","text":"为了确保资源的整体性,Angular Service Worker 会验证所有带哈希的资源的哈希值。 通常,对于 CLI 应用程序,用户的 src/ngsw-config.json配置文件中会涵盖 dist 目录下的所有内容。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":70,"length":20,"style":"CODE"},{"offset":99,"length":4,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056149,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":19,"content":{"blocks":[{"key":"d9mj8","text":"如果某个特定的文件未能通过验证,Angular Service Worker 就会尝试用 “cache-busting” URL 为参数重新获取内容,以消除浏览器或中间缓存的影响。 如果该内容也未能通过验证,则 Service Worker 会认为该应用的整个版本都无效,并停止用它提供服务。 如有必要,Service Worker 会进入安全模式,这些请求将退化为直接访问网络。 如果服务无效、损坏或内容过期的风险很高,则会选择不使用缓存。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056150,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":20,"content":{"blocks":[{"key":"1o813","text":"导致哈希值不匹配的原因有很多:","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056151,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":21,"content":{"blocks":[{"key":"6d8if","text":"在源服务器和最终用户之间缓存图层可能会提供陈旧的内容。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]},{"key":"6cc5b","text":"非原子化的部署可能会导致 Angular Service Worker 看到部分更新后的内容。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]},{"key":"45fkd","text":"构建过程中的错误可能会导致更新了资源,却没有更新 ngsw.json。 反之,也可能发生没有更新资源,却更新了 ngsw.json 的情况。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[{"offset":25,"length":9,"style":"CODE"},{"offset":56,"length":9,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056152,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":22,"content":{"blocks":[{"key":"dl45g","text":"不带哈希的内容","type":"header-four","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056153,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":23,"content":{"blocks":[{"key":"cajj2","text":"ngsw.json 清单中唯一带哈希值的资源就是构建清单时 dist 目录中的资源。 而其他资源,特别是从 CDN 加载的资源,其内容在构建时是未知的,或者会比应用程序部署得更频繁。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":0,"length":9,"style":"CODE"},{"offset":30,"length":4,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056154,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":24,"content":{"blocks":[{"key":"46rk0","text":"如果 Angular Service Worker 没有哈希可以验证给定的资源,它仍然会缓存它的内容,但会使用 “重新验证时失效” 的策略来承认HTTP缓存头。 也就是说,当被缓存资源的 HTTP 缓存头指出该资源已过期时,Angular Service Worker 将继续提供内容,并尝试在后台刷新资源。 这样,那些被破坏的非哈希资源留在缓存中的时间就不会超出为它配置的生命周期。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056155,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":25,"content":{"blocks":[{"key":"f8rku","text":"App 选项卡","type":"header-three","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056156,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":26,"content":{"blocks":[{"key":"6ajqp","text":"如果应用程序的资源版本突然发生了变化或没有给出警告,就可能会有问题。有关这些问题的描述,请参阅前面的 版本 部分。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[{"offset":51,"length":2,"key":3}],"data":[]}],"entityMap":{"3":{"type":"LINK","mutability":"MUTABLE","data":{"url":"https://angular.cn/guide/service-worker-devops#versions"}}}}},{"id":100056157,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":27,"content":{"blocks":[{"key":"b43u3","text":"Angular Service Worker 会保证:正在运行的应用程序会继续运行和当前应用相同的版本。 而如果在新的 Web 浏览器选项卡中打开了该应用的另一个实例,则会提供该应用的最新版本。 因此,这个新标签可以和原始标签同时运行不同版本的应用。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056158,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":28,"content":{"blocks":[{"key":"67qlv","text":"值得注意的是,这种担保比普通的 Web 部署模型提供的担保还要更强一点。 如果没有 Service Worker,则不能保证稍后在这个正在运行的应用中惰性加载的代码 和其初始代码的版本是一样的。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":31,"length":4,"style":"BOLD"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056159,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":29,"content":{"blocks":[{"key":"6o4ep","text":"Angular Service Worker 为什么可能会更改运行中的应用的版本有几个有限的原因。 其中一些是因为出错了:","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056160,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":30,"content":{"blocks":[{"key":"dq425","text":"由于哈希验证失败,当前版本变成了无效的。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]},{"key":"4qjgv","text":"某个无关的错误导致 Service Worker 进入了安全模式,或者说,它被暂时禁用了。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056161,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":31,"content":{"blocks":[{"key":"b9sos","text":"Angular Service Worker 能知道在任何指定的时刻正在使用哪些版本, 并清除那些没有被任何选项卡使用的版本。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056162,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":32,"content":{"blocks":[{"key":"21gvf","text":"另一些可能导致 Angular Service Worker 在运行期间改变版本的因素是一些正常事件:","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056163,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":33,"content":{"blocks":[{"key":"4h01v","text":"页面被重新加载/刷新。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]},{"key":"87jc7","text":"该页面通过 SwUpdate 服务请求立即激活这个更新。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[{"offset":6,"length":8,"style":"CODE"}],"entityRanges":[{"offset":6,"length":8,"key":4}],"data":[]}],"entityMap":{"4":{"type":"LINK","mutability":"MUTABLE","data":{"url":"https://angular.cn/api/service-worker/SwUpdate"}}}}},{"id":100056164,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":34,"content":{"blocks":[{"key":"996tf","text":"Service Worker 更新","type":"header-three","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056165,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":35,"content":{"blocks":[{"key":"64mia","text":"Angular Service Worker 是一个运行在Web浏览器中的小脚本。 有时,这个 Service Worker 也可能会需要更新,以修复错误和增强特性。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056166,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":36,"content":{"blocks":[{"key":"533ui","text":"首次打开应用时或在一段非活动时间之后再访问应用程序时,就会下载 Angular Service Worker。 如果 Service Worker 发生了变化,Service Worker 就会在后台进行更新。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056167,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":37,"content":{"blocks":[{"key":"2iuba","text":"Angular Service Worker 的大部分更新对应用程序来说都是透明的 - 旧缓存仍然有效,其内容仍然能正常使用。 但是,在 Angular Service Worker 中可能偶尔会有错误修复或新功能,需要让旧的缓存失效。 这时,应用程序就从会网络上透明地进行刷新。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056168,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":38,"content":{"blocks":[{"key":"5407g","text":"调试 Angular Service Worker","type":"header-two","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056169,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":39,"content":{"blocks":[{"key":"7nm42","text":"偶尔,可能会需要检查运行中的 Angular Service Worker,以调查问题或确保它在按设计运行。 浏览器提供了用于调试 Service Worker 的内置工具,而且 Angular Service Worker 本身也包含了一些有用的调试功能。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056170,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":40,"content":{"blocks":[{"key":"andjn","text":"定位并分析调试信息","type":"header-three","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056171,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":41,"content":{"blocks":[{"key":"1s1if","text":"Angular Service Worker 会在虚拟目录 ngsw/ 下暴露出调试信息。 目前,它暴露的唯一的 URL 是 ngsw/state。 下面是这个调试页面中的一段范例内容:","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":30,"length":5,"style":"CODE"},{"offset":63,"length":10,"style":"CODE"}],"entityRanges":[{"offset":68,"length":5,"key":5}],"data":[]}],"entityMap":{"5":{"type":"LINK","mutability":"MUTABLE","data":{"url":"https://angular.cn/api/animations/state"}}}}},{"id":100056172,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":42,"content":{"blocks":[{"key":"eb86m","text":"content_copyNGSW Debug Info: Driver state: NORMAL ((nominal))Latest manifest hash: eea7f5f464f90789b621170af5a569d6be077e5cLast update check: never === Version eea7f5f464f90789b621170af5a569d6be077e5c === Clients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100f65 === Idle Task Queue ===Last update tick: 1s496uLast update run: neverTask queue: * init post-load (update, cleanup) Debug log:","type":"code-block","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{"syntax":"javascript"}}],"entityMap":[]}},{"id":100056173,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":43,"content":{"blocks":[{"key":"6uad4","text":"驱动程序的状态","type":"header-four","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056174,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":44,"content":{"blocks":[{"key":"1peiq","text":"第一行表示驱动程序的状态:","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056175,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":45,"content":{"blocks":[{"key":"bakkv","text":"content_copyDriver state: NORMAL ((nominal))","type":"code-block","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{"syntax":"javascript"}}],"entityMap":[]}},{"id":100056176,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":46,"content":{"blocks":[{"key":"9mj8t","text":"NORMAL 表示这个 Service Worker 正在正常运行,并且没有处于降级运行的状态。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":0,"length":6,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056177,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":47,"content":{"blocks":[{"key":"8p3su","text":"有两种可能的降级状态:","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056178,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":48,"content":{"blocks":[{"key":"fhul0","text":"EXISTING_CLIENTS_ONLY:这个 Service Worker 没有该应用的最新已知版本的干净副本。 较旧的缓存版本可以被安全的使用,所以现有的选项卡将继续使用较旧的版本运行本应用, 但新的应用将从网络上加载。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[{"offset":0,"length":21,"style":"CODE"}],"entityRanges":[],"data":[]},{"key":"b6e2j","text":"SAFE_MODE:Service Worker 不能保证使用缓存数据的安全性。 发生了意外错误或所有缓存版本都无效。 这时所有的流量都将从网络提供,尽量少运行 Service Worker 中的代码。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[{"offset":0,"length":9,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056179,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":49,"content":{"blocks":[{"key":"3igdg","text":"在这两种情况下,后面的括号注解中都会提供导致 Service Worker 进入降级状态的错误信息。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056180,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":50,"content":{"blocks":[{"key":"7qlie","text":"最新清单的哈希","type":"header-four","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056181,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":51,"content":{"blocks":[{"key":"dfvmm","text":"content_copyLatest manifest hash: eea7f5f464f90789b621170af5a569d6be077e5c","type":"code-block","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{"syntax":"javascript"}}],"entityMap":[]}},{"id":100056182,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":52,"content":{"blocks":[{"key":"76ikb","text":"这是 Service Worker 所知道的应用最新版本的 SHA1 哈希值。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056183,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":53,"content":{"blocks":[{"key":"6ucf1","text":"最后一次更新检查","type":"header-four","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056184,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":54,"content":{"blocks":[{"key":"930bv","text":"content_copyLast update check: never","type":"code-block","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{"syntax":"javascript"}}],"entityMap":[]}},{"id":100056185,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":55,"content":{"blocks":[{"key":"4v9dd","text":"这表示 Service Worker 最后一次检查应用程序的新版本或更新的时间。“never” 表示 Service Worker 从未检查过更新。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056186,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":56,"content":{"blocks":[{"key":"80beq","text":"在这个调试文件范例中,这次更新检查目前是已排期的,如下一节所述。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056187,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":57,"content":{"blocks":[{"key":"arq1b","text":"版本","type":"header-four","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056188,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":58,"content":{"blocks":[{"key":"5d4sk","text":"content_copy=== Version eea7f5f464f90789b621170af5a569d6be077e5c ===\n\nClients: 7b79a015-69af-4d3d-9ae6-95ba90c79486, 5bc08295-aaf2-42f3-a4cc-9e4ef9100f65","type":"code-block","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{"syntax":"javascript"}}],"entityMap":[]}},{"id":100056189,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":59,"content":{"blocks":[{"key":"1s7da","text":"在这个例子中,Service Worker 拥有一个版本的应用程序缓存并用它服务于两个不同的选项卡。 请注意,这个版本哈希值是上面列出的“最新清单的哈希”。 它的两个客户运行的都是最新版本。每个客户都用浏览器中 Clients API的 ID 列了出来。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":106,"length":7,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056190,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":60,"content":{"blocks":[{"key":"cjfrv","text":"空闲任务队列","type":"header-four","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056191,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":61,"content":{"blocks":[{"key":"e2pjk","text":"content_copy=== Idle Task Queue ===\nLast update tick: 1s496u\nLast update run: never\nTask queue:\n\n * init post-load (update, cleanup)","type":"code-block","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{"syntax":"javascript"}}],"entityMap":[]}},{"id":100056192,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":62,"content":{"blocks":[{"key":"4unhg","text":"空闲任务队列是 Service Worker 中所有在后台发生的未决任务的队列。 如果这个队列中存在任何任务,则列出它们的描述。 在这个例子中,Service Worker 安排的任务是一个用于更新检查和清除过期缓存的后期初始化操作。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056193,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":63,"content":{"blocks":[{"key":"28jd9","text":"最后的 tick/run 计数器给出了与特定事件发生有关的空闲队列中的时间。 “Last update run” 计数器显示的是上次执行空闲任务的时间。 “Last update tick” 显示的是自上次事件以来可能要处理的队列的时间。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056194,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":64,"content":{"blocks":[{"key":"4ir61","text":"调试日志","type":"header-four","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056195,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":65,"content":{"blocks":[{"key":"6c00u","text":"content_copyDebug log:","type":"code-block","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{"syntax":"javascript"}}],"entityMap":[]}},{"id":100056196,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":66,"content":{"blocks":[{"key":"2kpq8","text":"在 Service Worker 中出现的任何错误都会记录在这里。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056197,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":67,"content":{"blocks":[{"key":"7qa5r","text":"开发者工具","type":"header-three","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056198,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":68,"content":{"blocks":[{"key":"boc19","text":"Chrome 等浏览器提供了能与 Service Worker 交互的开发者工具。 这些工具在使用得当时非常强大,但也要牢记一些事情。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056199,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":69,"content":{"blocks":[{"key":"cd929","text":"使用开发人员工具时,Service Worker 将继续在后台运行,并且不会重新启动。 这可能会导致开着 Dev Tools 时的行为与用户实际遇到的行为不一样。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]},{"key":"5u1vk","text":"如果你查看缓存存储器的查看器,缓存就会经常过期。右键单击缓存存储器的标题并刷新缓存。","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056200,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":70,"content":{"blocks":[{"key":"d2bou","text":"在 Service Worker 页停止并重新启动这个 Service Worker 将会触发一次更新检查。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056201,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":71,"content":{"blocks":[{"key":"9famq","text":"Service Worker 的安全性","type":"header-two","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056202,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":72,"content":{"blocks":[{"key":"30gjs","text":"像任何复杂的系统一样,错误或损坏的配置可能会导致 Angular Service Worker 以不可预知的方式工作。 虽然它在设计时就尝试将此类问题的影响降至最低,但是,如果管理员需要快速停用 Service Worker, Angular Service Worker 也包含多种故障保护机制。","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056203,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":73,"content":{"blocks":[{"key":"evevi","text":"故障保护机制","type":"header-three","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056204,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":74,"content":{"blocks":[{"key":"7q34h","text":"要停用 Service Worker,请删除或重命名 ngsw-config.json 文件。 当 Service Worker 对 ngsw.json 的请求返回 404 时,Service Worker 就会删除它的所有缓存并注销自己,本质上就是自毁。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":27,"length":16,"style":"CODE"},{"offset":67,"length":9,"style":"CODE"},{"offset":83,"length":3,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056205,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":75,"content":{"blocks":[{"key":"5d6i3","text":"Safety Worker","type":"header-three","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056206,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":76,"content":{"blocks":[{"key":"dbf86","text":"@angular/service-worker NPM 包中还包含一个小脚本safety-worker.js,当它被加载时就会把它自己从浏览器中注销。 这个脚本可以作为终极武器来摆脱那些已经安装在客户端页面上的不想要的 Service Worker。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":0,"length":23,"style":"CODE"},{"offset":38,"length":16,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056207,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":77,"content":{"blocks":[{"key":"1u432","text":"要特别注意的是,你不能直接注册这个 Safety Worker,因为具有已缓存状态的旧客户端可能无法看到一个新的、用来安装 另一个 worker 脚本的 index.html。 相反,你必须在想要注销的 Service Worker 脚本的 URL 中提供 safety-worker.js 的内容, 而且必须持续这样做,直到确定所有用户都已成功注销了原有的 Worker。 对大多数网站而言,这意味着你应该永远为旧的 Service Worker URL 提供 这个 Safety Worker。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":77,"length":10,"style":"CODE"},{"offset":129,"length":16,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}},{"id":100056208,"sectionId":1489572,"chapterId":18012,"documentId":1264,"rank":78,"content":{"blocks":[{"key":"8gc4t","text":"这个脚本可以用来停用 @angular/service-worker 以及任何其它以前在你的站点上提供过的 Service Worker。","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":11,"length":23,"style":"CODE"}],"entityRanges":[],"data":[]}],"entityMap":[]}}]},"fetchStatus":"none","searchStatus":"none","isSearching":false,"keyword":"","searchResult":[],"pageNumber":1,"pageSize":20,"total":0,"done":false,"path":"section"},"isCampusAmabassadorWhiteListUser":false,"env":"production","documentBaseTitle":"腾讯云开发者社区-腾讯云","cdnDomain":"cloudcache.tencent-cloud.cn","cssDomain":"cloudcache.tencent-cloud.cn","qcloudDomain":"cloud.tencent.com","consoleDomain":"console.cloud.tencent.com","qcommunity_identify_id":"tt7_jHCACztU1smwlND31","session":{"isLogined":false,"isQcloudUser":false,"isOwner":false,"nickname":"","accountInfoCompleted":false,"phoneCompleted":false,"profile":{},"contactPhoneCompleted":false,"userInfo":{},"phoneMainland":false},"pvId":"UaoV2kM8qwrMUPSHf_ZUd","userIp":"8.222.208.146","fromMiniProgram":false,"route":{"url":"/developer/section/1489572","path":"/developer/section/1489572","pathname":"/developer/section/1489572","search":null,"query":{},"segments":["developer","section","1489572"]}}); </script><script class=""> if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; if (!Element.prototype.closest) Element.prototype.closest = function(s) { var el = this; if (!document.documentElement.contains(el)) return null; do { if (el.matches(s)) return el; el = el.parentElement; } while (el !== null); return null; }; window.addEventListener('mouseover', function(evt) { const target = evt.target; if (!target) { return; } const aEle = target.closest('a'); if (!aEle) { return; } let href = aEle.getAttribute('href'); if (!href) { return; } href = href.replace(/cloud.tencent.com.cn|cloud.tencent.com|cloud.tencent.cn/g, 'cloud.tencent.com'); aEle.setAttribute('href', href); }, true); </script></body></html>