使用History API的单页应用(SPA)部署是否应采用HTTP内容协商?
SPA History 模式部署最佳实践解答
1. 单页应用HTML资源的正确服务方式是什么?
- 先做静态资源优先匹配:所有已知路径的静态资源(js、css、图片、字体等)按路径正常返回,匹配不到直接返回
404,尤其是带固定前缀的静态资源路径(如/assets/、/static/开头的路径)不要走HTML兜底逻辑。 - 仅对未匹配到静态资源、且明确需要HTML的请求,返回SPA入口HTML文件,同时对入口HTML设置
Cache-Control: no-cache的缓存策略,避免用户加载到旧版本的入口文件。 - 应用内部做好前端路由匹配,未命中前端路由的场景展示应用自定义的404页面。
2. 整个部署流程是否应当引入HTTP内容协商?
应当引入,该用法不属于内容协商的不当使用。
实际生产场景中引入内容协商判断Accept请求头,仅对接受HTML的请求返回兜底HTML,可以完美解决资源路径拼写错误时返回HTML而非404的问题,且该方案已经被connect-history-api-fallback等主流生态库验证多年,实用性远高于理论层面的语义纠结。
若采用内容协商方案,未知资源且客户端不接受HTML时的处理规则:
1. 是否应当优先返回406 Not Acceptable响应而非404 Not Found响应?
优先返回404,不要使用406。
该场景的核心语义是「请求的资源不存在」,而非「资源存在但没有符合要求的表示形式」,返回404更符合开发者和客户端的常规认知。同时406在实际生产中使用极少,错误提示的可读性和兼容性远不如404,也和主流生态实现保持一致。
2. 响应体应当包含什么内容?
- 静态资源类请求:按常规
404逻辑返回即可,比如图片请求可以返回空内容或者通用404占位图,接口请求返回标准结构的JSON错误信息。 - 不需要做特殊的自定义响应内容,保持和普通静态服务的404逻辑一致即可。
3. 需要额外配置哪些请求头以保证系统行为合规?
- 必须配置
Vary: Accept响应头:由于同一路径会根据Accept请求头返回不同内容(入口HTML或者404),该头可以保证CDN、浏览器缓存能正确区分不同响应,避免出现资源请求缓存到HTML内容的问题。 - 入口HTML的缓存头固定配置为
Cache-Control: no-cache,确保用户每次都能拿到最新的入口文件,不会因为缓存导致应用更新不生效。 - 其他静态资源的缓存规则保持原有逻辑即可,带哈希值的可缓存资源可正常设置长时间强缓存。
内容的提问来源于stack exchange,提问作者ezzatron
相关产品推荐
相关产品推荐

