想象你是一位城堡领主,正在建造一座崭新的城堡——这就是你的 PWA 应用。城堡不仅要住得气派(功能好用),更要守得住(安全可靠)。一座真正坚固的城堡需要什么?需要护城河和吊桥挡住外敌(HTTPS 加密传输),需要城门口的卫兵逐一查验访客的身份与来历(CSP 内容安全策略),需要仓库管理员清点物资、防止假货混入(Service Worker 缓存校验),还需要时刻提防伪装成自己人的间谍(XSS 攻击防护)。本篇文章将带你从零开始,像搭建城堡一样一步步把「数字城堡」修建得固若金汤。你不必懂深奥的密码学,也不必会写攻击代码,只要跟着故事走,就能掌握 PWA 安全策略的核心知识。
PWA 安全策略是 Web 应用走向生产环境的第一道生命线。掌握 HTTPS、CSP、混合内容治理与 XSS 防护,是前端与全栈工程师的必备基本功,也是应对安全面试高频考点的关键筹码。
目录
可视化演示
展示PWA安全三大核心:HTTPS与混合内容(TLS四步握手加密通道+混合内容自动阻断防降级攻击)、CSP内容安全策略(五大指令default/script/style/img/connect-src白名单XSS拦截100%)、Service Worker缓存安全(同源验证+CORS+签名+过期四重校验防缓存投毒),三模式切换理解PWA安全全貌。
本节配有交互动效(进入视口后自动加载,约 3KB)。
'+C1+'
HTTPS 加密通信:城堡的护城河与吊桥
中世纪的城堡建造者们有一条颠扑不破的准则:先挖护城河,再铸吊桥。没有护城河的城堡,就像敞着大门迎接敌军。对于 PWA 应用而言,HTTPS 就是那条护城河与那座吊桥。它保证了用户在访问你的站点时,信息在网络上传输的过程是一条「只有你和服务器知道的密道」。任何路过的窃听者,看到的都只是河面上平静的涟漪,而不是水底藏着的珍宝。
在 HTTP 时代,浏览器和服务器之间的通信就像在集市广场上大声喊话,任何路过的人都能听清你说了什么。而 HTTPS 在 HTTP 之上叠加了一层 TLS 加密协议,把「喊话」变成了「加密飞鸽传书」。即使信鸽被半路拦截,攻击者看到的也只是一堆无法解读的乱码,无法得知你发送的账号密码和聊天内容。
从技术实现看,HTTPS 的加密通道由三部分构成。第一是机密性:数据被对称加密算法加密,攻击者截获数据也无法读取。第二是完整性:TLS 通过消息认证码保证数据在传输中未被篡改,哪怕只改了一个字节,接收方也能立刻察觉「封印被破坏」。第三是真实性:服务器必须持有由数字证书机构(CA)签发的证书,相当于服务器的「身份证」,浏览器在建立连接时先查验身份证,确认自己没有找错城门。
这就是你的护城河:数据在河里游过,岸上的人看不见;水被搅动过,你能立刻察觉;而且你只认那座吊桥上的城徽。不过,光是挖了护城河还不够——很多城堡在遭到攻击时才发现,有些访客还在走「老路」(HTTP 明文访问)。为此,还有一道叫 HSTS 的「铁律」:服务器通过响应头告诉浏览器,未来一段时间内只许走 HTTPS 吊桥,彻底堵死明文访问的老路。
- 机密性(加密)数据在传输前被 TLS 加密成密文,窃听者看到的是乱码。
- 完整性(签名)发送方用密钥为内容生成一段「指纹」,接收方比对指纹验证内容未被调包。
- 真实性(证书)CA 机构为服务器公钥盖上数字签章,浏览器验证签章有效后才建立连接。
内容安全策略:城门口的安保门禁
城堡有了护城河,并不意味着什么人都能往里放。你需要一名严格的安保队长守在城门口,手里拿着一份「访客名单」——这份名单就是内容安全策略(CSP)。它不像护城河那样挡住物理入侵,而是挡住「资源入侵」:页面上的每一个脚本、图片、样式、连接请求,都必须经过安保队长查验来源,名单上没有的「身份不明人员」一律拒之门外。
CSP 是服务器通过 HTTP 响应头返回给浏览器的一套门禁规则:Content-Security-Policy 头里写明了哪些来源的资源可以被页面加载。这份名单还能细分:运粮草的走西门(img-src 管图片)、运兵器的走东门(script-src 管脚本)、运石料的走北门(style-src 管样式)、传递军情走密道(connect-src 管 fetch/XHR 请求)。每个城门都有一份独立名单,互不混淆。
CSP 的核心是「指令 + 源列表」的配置组合。每个指令对应一类资源:script-src 限制脚本来源、img-src 限制图片来源、connect-src 限制请求目标。如果某个资源类型没有写具体的指令怎么办?default-src 作为兜底策略,统一约束所有未单独指定指令的资源类型。这就像城门守卫的「默认规则」:没有特别通行证的事物,统一走规定的正门,不能乱窜。
有了这份访客名单,即使有间谍混进了运输队,城门口的守卫也能一眼识破——因为他不在名单上。CSP 的精髓就是把攻击者挡在城墙之外,而不是等敌人进了城堡再内部排查。值得一提的是,CSP 还支持 report-uri / report-to 上报机制:凡是试图闯入的「可疑分子」,守卫都会写一封举报信交给城堡主人(开发者),方便你持续加固防线。
- 指令(Directive)每条规则管一类资源,例如 script-src 只约束脚本加载。
- 源列表(Source List)指令后面列出的允许加载的来源集合,来源必须精确匹配。
- 默认兜底(default-src)未单独配置指令的资源类型,使用 default-src 的源列表作为最终裁决。
混合内容治理:城堡装修的建材质检
城堡的主墙虽然用的是坚固的花岗岩(HTTPS),但如果工匠在修补窗户时偷懒,混入了几根易燃的木料(HTTP 资源),整面墙的防火性能都会大打折扣。这种「在 HTTPS 页面里加载 HTTP 子资源」的现象,就是混合内容。页面本身是安全传输的,可某些子资源却是明文运输的,防线就这样被撕开了一道口子。
混合内容的危险在于,攻击者可以在网络链路上篡改那些明文传输的资源。比如你的页面加载了一张来自 HTTP 地址的图片,攻击者把「普通的风景图」替换成「带有恶意像素数据的图片」,甚至把图片内容改为一段用来攻击的脚本载荷——只要浏览器信任了这个混合内容来源,整座城堡就可能被攻陷。
浏览器对混合内容的处理取决于资源类型,可以分为两级。主动混合内容(脚本、iframe、样式表、fetch 请求)有能力直接篡改页面行为,浏览器一律硬性拦截。被动混合内容(图片、音频、视频)的危险性相对低,浏览器通常降级为「警告」,但资源仍然会加载。开发者可以通过 CSP 的 upgrade-insecure-requests 指令,让浏览器自动把页面上的 HTTP 资源升级为 HTTPS 请求;如果资源不支持 HTTPS,则会被拦截。
城堡的质检员不仅要检查主墙的石料,还要检查每一扇窗户用的木材、每一件家具的材料。哪怕是墙上挂的一幅画,也得确认它的来源可靠——否则,一幅画也可能成为敌人潜入的暗道。好消息是,现代浏览器和 CSP 已经给了你趁手的工具:靠 upgrade-insecure-requests 自动升级,再用浏览器的混合内容告警逐一排查,就能把不合格的「建材」全部换掉。
- 安全(全 HTTPS)所有子资源请求都使用 HTTPS 协议,无任何明文传输。
- 警告(被动内容)图片、音视频等资源走 HTTP,浏览器标记为警告但仍会加载。
- 危险(主动内容)脚本、iframe 等可执行资源走 HTTP,浏览器直接拦截并阻断加载。
Service Worker 缓存安全:城堡的物资仓库
城堡里有一位神秘的仓库管理员,他会在和平时期把粮食和武器提前存进仓库,等到围城断网时再拿出来用——这就是 Service Worker。它让你的 PWA 在离线时也能打开,像极了城堡的应急储备粮。用户再也不用担心地铁隧道里没信号就打不开你的应用了。
但仓库管理有个致命问题:如果敌人买通了运粮的商贩,把假粮食混进仓库,围城时你打开仓库才发现全是沙子,那就太晚了。因此,仓库管理员必须对每一批入仓的物资进行严格检查:看发货单(缓存版本)、查验封印(资源校验和)。任何「三无产品」都不得入库,任何标签模糊的「临期物资」都要及时清理。
Service Worker 缓存安全的核心策略有四条。第一,版本管理:给每个缓存命名并附带版本号,如 my-cache-v1,版本不在白名单中的缓存一律作废。第二,校验机制:缓存资源时记录资源的哈希校验和,读取时比对当前资源与缓存资源的校验和,防止缓存内容被篡改。第三,更新与清理:新版本发布时立即拉取新资源并主动删除旧缓存,避免新旧资源混用引发的安全漏洞。第四,敏感数据保护:绝不把 token、用户资料等敏感信息写入 Cache Storage,应放入 IndexedDB 并配合加密方案存储。
一个合格的仓库管理员,既要保证「围城时拿得出物资」(离线可用),又要保证「拿出来的物资没被掉包」(版本与校验)。有了这两条,城堡的粮仓才能让人放心。记住:仓库不是保险箱,钥匙(缓存权限)要攥紧,货物(敏感数据)不能随便堆。
- 版本白名单只接受版本号在允许列表中的缓存,其余视为过期或不可信。
- 校验和匹配缓存内容的哈希值必须与服务器下发的一致,防止被调包。
- 更新触发版本不一致时,立即从网络重新获取资源并更新缓存。
XSS 漏洞防护:城堡的身份验证
如果说 CSP 是把陌生人挡在城门外,那么 XSS(跨站脚本攻击)就是「潜伏者作案」:攻击者把自己伪装成一位合法访客,混进城堡之后,偷偷在公告栏上贴了一张写着咒语的纸条。任何路过的人念出纸条上的咒语,就会被诅咒控制——这段咒语,就是攻击者注入的恶意脚本。
XSS 的本质是:用户输入的数据被当成了可执行的代码。比如一个评论功能,用户输入 <script>偷取Cookie</script>,如果网站没有做任何处理,这段「评论」就会被浏览器当作脚本执行,直接偷走其他用户的登录凭证。开发者的本意只是「显示一段文字」,浏览器却把它「执行成了一行命令」。
防御 XSS 需要三道防线协同作战。第一道,输入过滤:对用户输入的内容进行白名单校验,移除掉 <script>、onerror 等危险标签和属性。第二道,输出编码:在把数据渲染到页面时,把 <、> 等特殊字符转义为 <、>,让浏览器把它们当作文本而不是代码。第三道,CSP 兜底:即使前两道防线被突破,恶意脚本成功注入了页面,CSP 的 script-src 规则也会限制脚本来源,让注入的脚本因「不在名单上」而无法执行。
你的城堡再坚固,也架不住间谍在里面搞破坏。XSS 防护就是城堡的「内部安检系统」:进城门时检查身份(输入过滤),公告栏张贴时审核内容(输出编码),城堡里安排巡逻守卫(CSP 兜底)。三层防线相辅相成,才能把「贴咒语」的间谍彻底防死。
- 输入过滤过滤掉用户输入中的危险标签和事件属性。
- 输出编码渲染时把特殊字符转义为 HTML 实体,浏览器不再当作标签解析。
- CSP 兜底即使恶意脚本被注入,CSP 也拒绝加载攻击者域名的脚本。
安全配置实践:城堡守卫的日常巡逻
城堡建得再坚固,如果守卫从不巡逻、从不检查城墙裂缝,迟早会出问题。安全不是一次性的工程,而是日复一日的坚持。很多 PWA 上线时一切正常,几个月后就因为一次依赖库升级、一条新加的第三方脚本而出现漏洞——这就是「平时不巡逻」的代价。
对 PWA 应用来说,「日常巡逻」就是一系列安全配置的规范落地。这些配置本身不复杂,但每一件都像一个「巡逻打卡点」,漏掉一个,就可能在关键时刻掉链子。巡逻不是轰轰烈烈的战斗,而是琐碎的、重复的、但绝对必要的坚持。
具体来说,有四类「巡逻任务」。第一,安全响应头配置:除了 CSP,还要设置 HSTS(强制 HTTPS)、X-Content-Type-Options: nosniff(禁止 MIME 嗅探)、X-Frame-Options: DENY(防点击劫持)。第二,权限策略管理:通过 Permissions-Policy 限制摄像头、麦克风、地理位置等敏感 API 的使用范围,降低被恶意调用的风险。第三,密钥安全管理:所有 API 密钥、加密密钥都放进环境变量或密钥管理服务(KMS),绝不硬编码进前端代码——因为前端代码对用户是完全透明的。第四,定期安全审计:使用 Lighthouse、Security Headers 等工具定期扫描,持续跟踪安全评分变化。
城堡的安全不是靠某一件神器,而是靠日复一日的巡逻与维护。每一道裂缝(安全头缺失)、每一处堆放杂物的角落(密钥泄露风险),都可能成为敌人攻入的突破口。坚持日常巡逻,城堡才能长治久安——PWA 亦如是。
- 检查项每项安全配置的完成情况,完成取 1,未完成取 0。
- 权重不同检查项对整体安全的重要性不同。
- 加权求和所有检查项的加权得分汇总为整体安全评分。
AI 应用场景
场景一:AI 驱动的 PWA 安全审计
阶段:安全检测与自动化评估
解决的问题:传统安全审计依赖人工巡检,速度慢、容易遗漏。AI 可以自动分析页面的 CSP 策略配置、HTTPS 部署情况、混合内容告警,生成全面评估报告,并给出修复建议。它像一位不知疲倦的城堡巡夜人,每晚把城墙、仓库、城门全部巡检一遍。
具体案例:某大型电商 PWA 引入 AI 审计系统,自动爬取 2000+ 页面,识别出 37 处混合内容引用和 12 处 CSP 配置过宽问题。修复后安全评分从 72 提升至 96,并通过了上线前的安全合规审查。
场景二:智能威胁识别与日志分析
阶段:实时监控与智能告警
解决的问题:Service Worker 的缓存请求日志数量庞大,人工无法实时分析异常模式。AI 可以对请求序列进行建模,识别出异常的缓存篡改尝试和 XSS 注入攻击。它像城堡里的「哨塔瞭望员」,用鹰眼扫描远处每一个可疑的移动。
具体案例:某资讯类 PWA 部署 AI 日志分析模块,通过聚类算法发现某个用户代理的请求序列异常,定位到一次针对 Service Worker 缓存的投毒攻击。及时阻断后,避免了大规模用户数据泄露。
场景三:定制化 CSP 策略自动生成
阶段:策略自动生成与优化
解决的问题:CSP 策略手工编写容易过严(误伤正常功能)或过松(失去防护意义)。AI 可以分析站点实际的资源加载图谱,自动生成「恰好够用」的白名单策略。就像给城堡训练了一支熟悉每位常客面孔的守卫队,既不让坏人混入,也不挡好人进门。
具体案例:开发团队用 AI 扫描生产环境的全部资源请求,自动生成 default-src 'self' 加各资源类型的精确源列表。策略部署后,误拦截率从 8% 降至 0.3%,同时成功拦截了 3 次异常脚本注入尝试。
Python 演示
import hashlibimport re class CSPPolicy: def __init__(self, policy_text: str): self.directives: dict = {} self._parse(policy_text) def _parse(self, text: str): for part in text.split(";"): tokens = part.strip().split() if tokens: self.directives[tokens[0]] = set(tokens[1:]) def allows(self, directive_name: str, url: str) -> bool: sources = self.directives.get( directive_name, self.directives.get("default-src", set()) ) for src in sources: if src == "'self'": return True if src == "'none'": return False if src.startswith("https://") and url.startswith(src.rstrip("/")): return True if src.startswith("//") and url.startswith("https:" + src): return True return False def check_all_resources(self, resources: dict) -> dict: return { directive: [url for url in urls if not self.allows(directive, url)] for directive, urls in resources.items() } class CacheValidator: def __init__(self, version_whitelist): self.version_whitelist = set(version_whitelist) def is_valid(self, cache_version: str, content: str, expect_hash: str) -> bool: if cache_version not in self.version_whitelist: return False actual_hash = hashlib.sha256(content.encode("utf-8")).hexdigest() return actual_hash == expect_hash def demo(): policy = CSPPolicy( "default-src 'self'; " "script-src 'self' https://cdn.example.com; " "img-src 'self' data:" ) resources = { "script-src": [ "https://cdn.example.com/app.js", "https://evil-site.com/x.js", "/scripts/main.js", ], "img-src": [ "/images/logo.png", "data:image/png;base64,abc", "http://insecure.com/pic.jpg", ], } blocked = policy.check_all_resources(resources) for directive, urls in blocked.items(): print(f"[{directive}] 被拦截的资源:") for url in urls: print(f" - {url}") validator = CacheValidator(["v1", "v2"]) content = "console.log('pwa app')" expect_hash = hashlib.sha256(content.encode("utf-8")).hexdigest() print("缓存校验:", validator.is_valid("v1", content, expect_hash)) print("缓存校验(版本过期):", validator.is_valid("v0", content, expect_hash)) if __name__ == "__main__": demo()
self.directives[tokens[0]] = set(tokens[1:])把每条 CSP 指令的源列表解析成集合,方便后续快速匹配。sources = self.directives.get(directive_name, ...)先查具体指令,找不到就回退到default-src兜底,这正是 CSP 的「默认规则」。if src == "'self'"'self'表示同源资源,属于常见的豁免项。urls if not self.allows(directive, url)筛选出「不被允许」的资源,即被门禁拦截的黑名单。self.version_whitelist = set(version_whitelist)版本白名单用集合存储,O(1) 快速判断缓存版本是否过期。actual_hash == expect_hash比对当前内容的 SHA256 哈希与服务器期望哈希,防止缓存被调包。
常见误区
误区我装了 SSL 证书,地址栏有小绿锁,PWA 就安全了,其他什么都不用管了。
正解HTTPS 只是打通了一条加密通道,相当于城堡的护城河。攻击者依然可以通过 XSS 漏洞、CSP 配置缺陷、混合内容等途径发起攻击。安全是一个体系,需要 HTTPS、CSP、Service Worker 缓存校验、输入输出防护协同作战。小绿锁只证明「这条河上有吊桥」,不证明「城堡里没有内鬼」。
为何常见:地址栏的小绿锁太有迷惑性,让人误以为浏览器认证了「网站是安全的」。实际上浏览器只认证了「传输是加密的」,两者有本质区别。
误区default-src 不是兜底所有指令吗?我只要写这一条就能防住所有攻击了。
正解default-src 只是「默认值」,如果页面需要加载外部域名的脚本、图片等资源,必须单独配置对应的指令。只写 default-src 'self' 会导致大量合法资源被拦截。于是开发者为了「修 bug」不断放宽策略,最后反而失去防护力。正确做法是根据实际资源加载情况,分指令精确配置。
为何常见:初学者容易把「兜底」理解成「一劳永逸」,忽略了 CSP 的粒度设计——兜底的意思是「没指定时用它」,而不是「只用它」。
误区浏览器不是会自动拦截混合内容吗?我不用管,让浏览器处理就好了。
正解浏览器只对主动混合内容(脚本、iframe)做硬拦截,被动混合内容(图片、音视频)只是警告但仍会加载,依然存在被篡改的风险。而且混合内容的存在本身就是「城堡的建材有隐患」,应该主动治理:升级资源到 HTTPS、配置 upgrade-insecure-requests,而不是把责任全部丢给浏览器。
为何常见:浏览器确实做了一部分拦截工作,这种「看似有兜底」的假象让人麻痹大意,忽略了被动内容的风险。
误区资源缓存到 Service Worker 里就永远不用更新了,反正断网也能用,一劳永逸。
正解缓存一旦过期,或被攻击者利用漏洞投毒,将长期危害所有用户。必须落实版本白名单、校验和比对和定期清理机制。敏感数据(token、用户资料)绝不能写入 Cache Storage,应放在 IndexedDB 并加密存储。仓库里的粮食要定期翻晒,否则会发霉。
为何常见:Service Worker 的「离线可用」特性太吸引人,容易让人忽略背后需要持续的版本治理与内容校验。
误区后端不是有参数校验吗?XSS 应该由后端过滤,前端只管渲染就好。
正解前端也是 XSS 防御的重要阵地。即使后端做了过滤,前端的 innerHTML 注入、DOM 操作、第三方脚本都可能引入 XSS 漏洞。输出编码、避免使用 innerHTML、配置 CSP 限制脚本来源,三者缺一不可。前后端各守一段防线,城堡才不会被两面夹击。
为何常见:Web 开发的前后端分工让很多人天然认为「安全归后端管」,忽略了前端渲染链路同样是攻击入口,尤其在现代前框架大量使用动态渲染的背景下。
面试题
Q1. CSP 中哪个指令用于限制脚本加载?
- A.img-src 限制图片来源
- B.script-src 限制脚本来源← 正确答案
- C.style-src 限制样式来源
- D.font-src 限制字体来源
答案:B。CSP 的每个指令管一类资源,script-src 专门负责脚本来源,是防 XSS 的核心指令。img-src 管图片、style-src 管样式、font-src 管字体,都不直接限制脚本,因此选 B。
Q2. 下列哪一项属于「主动混合内容」?
- A.页面中的普通图片资源
- B.页面中的背景音乐文件
- C.页面中嵌套的 iframe 框架← 正确答案
- D.页面中的视频播放文件
答案:C。主动混合内容是有能力篡改页面行为的资源,包括脚本、iframe、样式表、fetch 请求等;被动混合内容主要是图片、音频、视频。iframe 可以引入任意页面并执行脚本,属于主动内容,浏览器会直接拦截。
Q3. HTTPS 提供哪些安全属性?
- A.机密性防止数据被窃听← 正确答案
- B.完整性防止数据被篡改← 正确答案
- C.传输速度提升和缓存优化
- D.服务器身份的真实性验证← 正确答案
答案:ABD。HTTPS 通过加密提供机密性、通过 MAC 签名提供完整性、通过 CA 证书提供真实性。它不负责提升传输速度,也不属于缓存优化手段,宣传 HTTPS 会变快的说法没有依据。
Q4. HSTS 响应头的主要作用是什么?
- A.强制浏览器仅用 HTTPS 访问← 正确答案
- B.提升 HTTPS 的传输速度
- C.自动压缩网页中的资源文件
- D.禁用浏览器端的所有缓存
答案:A。HSTS 告诉浏览器「未来一段时间内只能通过 HTTPS 访问本站」,即使用户手动输入 HTTP 地址,浏览器也会自动改写为 HTTPS。它不负责加速、压缩或禁止缓存。
Q5. 浏览器遇到混合内容时的默认处理方式?
- A.无论类型全部拦截不加载
- B.无论类型全部警告后照常加载
- C.主动内容拦截被动内容警告← 正确答案
- D.自动升级请求为 HTTPS 再发送
答案:C。浏览器的默认策略是分级处理:主动混合内容(脚本、iframe)直接硬拦截,被动混合内容(图片、音视频)警告但继续加载。自动升级请求需要 upgrade-insecure-requests 指令配合,不是默认行为。
Q6. Service Worker 缓存安全的关键措施有哪些?
- A.缓存版本纳入白名单管理← 正确答案
- B.读取时比对资源校验和← 正确答案
- C.缓存容量越大越好永不清除
- D.敏感数据不存入 Cache Storage← 正确答案
答案:ABD。版本白名单和校验和比对能防止「过期缓存」与「被调包缓存」,敏感数据应放 IndexedDB 加密存储。缓存容量无限增长会占用用户存储空间并带来维护负担,不是安全做法。
Q7. CSP 中 default-src 的作用是什么?
- A.仅约束页面默认文档的加载
- B.兜底所有未单独指定的资源类型← 正确答案
- C.默认允许所有外部脚本执行
- D.自动为站点生成推荐的安全策略
答案:B。default-src 是为「没有写具体指令的资源类型」提供兜底源列表,比如你没配置 font-src,字体的加载就由 default-src 管。它不能自动生成策略,更不是「默认放行所有脚本」。
Q8. 下列哪些属于有效的 XSS 防护手段?
- A.对用户输入做白名单过滤← 正确答案
- B.渲染时对特殊字符做转义← 正确答案
- C.使用 innerHTML 直接拼接渲染
- D.配置 CSP 限制脚本执行来源← 正确答案
答案:ABD。输入过滤和输出编码是 XSS 防护的第一、第二道防线,CSP 是第三道兜底。innerHTML 直接拼接渲染恰恰是 XSS 的常见入口,会让用户输入被解析为 HTML 或脚本,是典型的反面操作。
Q9. CSP 指令 upgrade-insecure-requests 的作用是?
- A.立即拦截页面上所有 HTTP 子资源
- B.将页面的 HTTP 子资源自动升级为 HTTPS← 正确答案
- C.强制服务器端更新过期的 TLS 证书
- D.记录所有不安全的请求到报错日志
答案:B。该指令指示浏览器把页面中的 HTTP 子资源请求先改写为 HTTPS 再发送,相当于「主动升级」而非「被动拦截」。资源本身不支持 HTTPS 时才会被拦截,证书更新和日志记录则与它无关。
Q10. 下列哪项符合安全的缓存更新策略?
- A.版本更新时主动替换并清理旧缓存← 正确答案
- B.缓存一旦写入便永不更新使用
- C.每次请求都从网络重新下载全部资源
- D.只更新缓存但不校验资源内容
答案:A。安全的缓存更新应做到「新版本发布后主动拉取新资源、删除旧缓存」,既保证离线可用又不留过期隐患。永不更新会积累漏洞,每次全量下载浪费带宽,只更新不校验则可能让被篡改的内容混入仓库。