DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
PanstarCloud:部署应用,接入 AI,云服务器与 AI 网关
阿里云;从建站到云上业务;云服务器 · 数据库 · 对象存储;查看产品 →

Angular 下载链接跳到 Page Not Found,检查平台导航集成

withExperimentalPlatformNavigation会接管普通同源导航。22.2.3未排除下载与POST表单,按需撤掉该实验feature,保留RouterLink、原生提交及其他路由配置。

Angular 页面里的 <a download> 没有下载文件,地址栏反而变成 /report.csv,随后显示路由的 Page Not Found。如果启用了 withExperimentalPlatformNavigation(),要先检查下载是否被转换成了 SPA 导航,而不是先给服务器补一个 /report.csv 页面路由。

Angular 22.2.3 的这条实验性集成会处理应用 base href 下、同源且可以拦截的浏览器 navigate 事件。它排除了 reload,却没有把 downloadRequest 或携带 formData 的提交单独留给浏览器。22.2.1 的同类组合也会表现为下载不发生,或原生 POST 表单根本没发出请求。

普通链接也会进入路由器

未使用这项集成时,通常由 RouterLink 触发 Angular 的客户端路由。启用后,浏览器平台导航也接入路由器;即使下载链接没有 routerLink,也可能被拦截。单独删除一个本来就不存在的 routerLink,自然不会解决问题。

先比较浏览器中的真实节点和网络记录:链接保留了 download 属性,点击后却只出现客户端路由变化,没有预期文件请求;或 <form method="post"> 提交变成 URL 变化,服务端没有对应 POST。后者还可能使表单内容根本没有进入业务处理,不能仅凭地址栏跳转就显示提交成功。

下面是用来区分两条路径的局部模板,文件和提交地址须是测试环境真实存在的同源入口:

<a href="report.csv" download>下载报表</a>
<form method="post" action="submit">
  <input name="message" value="hello">
  <button type="submit">提交</button>
</form>

GET 表单、跨源链接、应用 base href 外的地址,以及浏览器不允许拦截的导航,需要按实际条件分别判断,不能说所有表单和下载都必然失效。

暂时撤掉平台导航集成,保留原路由配置

这项 API 当前仍属高度实验性的集成,官方要求仅用于实验和反馈,不用于生产。如果应用不需要它,可以从原有 provideRouter(routes, ...) 的 feature 列表中移除 withExperimentalPlatformNavigation(),并删除不再使用的导入。routes、其他 router features、认证守卫和应用 providers 都保持原有配置。

之后,应用内确需 SPA 跳转的入口继续使用 RouterLink;下载链接和原生表单由浏览器按其原本语义处理。原来因为这项集成才变成 SPA 导航的普通链接,也会恢复原生页面导航,应逐一确认页面刷新与状态保存符合产品要求。

不要用 preventDefault() 阻止下载后就结束处理,那只会让浏览器也不再下载。也不必把下载接口改成页面路由、把原生 POST 改成 GET,或忽略服务端的鉴权、CSRF 与文件响应头。

实验环境确需保留这项集成时,需要采用明确把这些事件交还浏览器的正式实现。22.2.3 的已发布包仍含上述拦截条件;主分支或某个下载相关修改,不能证明已安装版本修好了下载,更不能证明同时处理了 POST 表单。

看实际文件与请求,不只看导航错误消失

下载验收应确认文件内容、文件名及服务端必要的 Content-Type、Content-Disposition,不能只看不再进入 404 路由。表单验收则确认一次用户提交对应一次正确方法、正文和权限校验的请求,避免额外补一个 fetch 后与浏览器提交重复。

同一轮还要覆盖原有 RouterLink、前进后退、reload,以及项目 base href 下的普通链接。若 URL 确实按预期进入 Angular 路由,却由多个守卫选择了错误去向,那是另一条RedirectCommand 与守卫结果顺序路径,不能继续按下载拦截处理。