大家应该都有所体会,我们在使用由Angular,React,Vue等应用程序框架构建的客户端应用程序时,您总是会处理HTML5客户端路由,它将完全在浏览器中处理到页面和组件的客户端路由。几乎完全在浏览器中...
HTML5客户端路由在客户端上工作的很好,但是当深入链接到一个站点或在浏览器中按刷新时,客户端路由有一个恶习,变成服务器HTTP请求。请求可能未配置服务器的路由。
在这篇文章中,我将讨论如何使ASP.NET Core(或间接ASP.NET应用程序)通过有效地将客户端应用程序重新连接到其路由来处理这些“假”请求。下面话不多说了,来随着小编来一起看看详细的介绍吧。
Html 5客户端路由?
如果您不知道HTML5客户端路由是什么,请快速回顾一下。
客户端框架实现他们自己的客户端路由机制,以便他们可以 - 就像服务器应用程序 - 在页面或组件之间进行导航。
Angular支持几种路由类型:
哈希路线(http:// localhost:4200 /#!/ albums或http:// localhost:4200 /#/ albums)
HTML 5路线(http:// localhost:4200 / albums)
#!/ 哈希邦德路线
前者是一种较早的方法,它直接与HTTP语义一起工作,指定任何具有a的URL #在客户端被触发并跳转到页面内的“本地”URL。框架可以拦截导航并检查跟随的URL内容#以确定路线。散列爆炸#!用于区分应用程序URL和普通#锚链接。
散列爆炸路线的好处是,他们只是工作。没有服务器端出血的路线,如果您书签或刷新客户端页面,它只是如预期的那样工作,因为散列逻辑是作为浏览器中本地URL解析的一部分执行的。很简单,对吧?它只是工作。
但缺点是,如果您必须手动输入网址,则这些网址非常难看且不直观。对于散列爆炸路线来说,这并不是一个很好的论据,但是不管它们是否对HTML5路由不利。
哈希在Angular中的Bang路由
Angular使用默认的HTML5客户端路由,但它是一个简单的开关来启用Hashbang路由,而不是HTML5路由::
// in app.module.tsproviders : [ .. // make sure you use this for Hash Urls rather than HTML 5 routing { provide: LocationStrategy, useClass: HashLocationStrategy },]
只要您routerLink在HTML模板中使用链接网址,并router.navigate()在代码链接中使用,Angular交换机就会自动在两种模式之间进行切换。
在HTML中使用<a routerLink="/albums" />链接
在代码中使用: router.navigate(["/album",album.id])
HTML5路由
HTML5路由使用更复杂的方法 - 它使用HTML5的Pushstate API来控制客户端的路由并管理地址栏显示。
这种方法的优点是,使用HTML5 API相对容易操作,并且使用标准的无延伸路由约定,使用Web应用程序和API时,URL更加简洁,易于控制。
但是HTML5路由需要服务器的明确支持来正确理解哪些路由是服务器路由,哪些是客户路由。
没有服务器处理的HTML5路由问题
问题在于HTML5客户端路由与服务器路由无法区分。
:4200/albums可以很容易地将客户端URL作为服务器端URL。在完全在客户端上导航时,HTML5路线工作正常 - 应用程序可以拦截导航并在激活特定路线时路由到相应的客户端页面。
如果您使用深层链接导航到客户端驱动的应用程序,然后您将该页面书签为书签,然后使用该URL导航回到该页面,或者刷新当前活动页面,则会弹出问题。在这两种情况下,当浏览器请求路由时,客户端应用程序不运行,因此浏览器向服务器请求路由URL。但是,默认情况下不设置处理说/albums路线,所以你会得到一个错误。
如果您在ASP.NET Core应用程序中没有对HTML5路由设置进行任何特殊处理,您将在应用程序中打开错误页面,或者从Kestrel中选择此默认显示:
图1 - 未处理的客户端路由产生服务器错误
修复服务器上的客户端路由
那么你如何解决这个问题呢?
客户端SPA应用程序通常有一个或几个启动应用程序的静态页面。对于一个典型的Angular应用程序,该页面是index.html启动应用程序并启动客户端路由。大多数框架都足够聪明,可以在启动时检查当前路由,并移至首次访问请求的路由。
如果客户端路由从书签,链接或完全刷新被触发到服务器,则需要提供index.html并保持原始URL不变。
然后,客户端应用程序将自行引导,并且内部路由启动,以希望将您甩回书签/刷新位置。
从服务器提供Index.html
为了这个工作,你需要确保服务器只提供服务器负责的内容。
有几种方法可以做到这一点:
主机服务器URL重写
处理ASP.NET Core应用程序中的客户端路由
主机Web服务器上的URL重写
如果您在主流Web服务器上运行ASP.NET Core(或ASP.NET)应用程序,最简单且最有效的解决方案是重写客户端URL并为index.html给定的URL 提供内容。
在IIS上,您可以使用IIS重写模块来执行此操作。我最近在一篇博文中更详细地介绍了这一点:
ASP.NET核心应用程序的IIS重写规则
但是这里是相关的IIS重写规则: