手机版

如何应对ASP.NET芯HTML5客户端路由回退问题

时间:2021-09-03 来源:互联网 编辑:宝哥软件园 浏览:

大家应该都知道,当我们使用Angular、React、Vue等应用框架构建的客户端应用时,你会一直处理HTML5客户端路由,这将完全处理客户端路由到浏览器中的页面和组件。几乎完全在浏览器中.

HTML5客户端路由在客户端运行良好,但当深度链接到某个站点或在浏览器中按下Refresh时,客户端路由有一个坏习惯,变成了服务器HTTP请求。请求可能没有为服务器配置路由。

在本文中,我将讨论如何让ASP.NET核心(或间接的ASP.NET应用程序)通过有效地将客户端应用程序重新连接到其路由来处理这些“假”请求。下面就不多说了。让我们来看看边肖的详细介绍。

Html 5客户端路由?

如果你不知道什么是HTML5客户端路由,请快速查看。

客户端框架实现了自己的客户端路由机制,因此它们可以像服务器应用程序一样在页面或组件之间导航。

Angular支持多种布线类型:

哈希路由(http://localhost: 4200/#!/相册或http://localhost: 4200/#/相册)HTML5路由(http://localhost:4200/相册)#!/哈斯邦路线

前者是较早的方法,直接使用HTTP语义,指定任何带有# A的URL在客户端被触发,并跳转到页面中的“本地”URL。框架可以拦截导航并检查以下URL内容#以确定路线。哈希爆炸#!用于区分应用程序URL和普通#锚链接。

散列爆炸路线的优点是它们只是工作。服务器端没有出血路径。如果您为客户端页面添加书签或刷新客户端页面,它就会像预期的那样工作,因为哈希逻辑是作为浏览器中本地URL解析的一部分来执行的。很简单,对吧?只是工作。

但缺点是如果非要手动输入网址,这些网址非常难看,不直观。这不是哈希爆炸路由的好论据,而是它们是否对HTML5路由不利。

在Angular中使用哈希进行Bang路由

Angular使用默认的HTML5客户端路由,但它是一个简单的开关,用于启用Hashbang路由,而不是HTML5路由:3360

//in app . module . ts providers :[.//确保将此用于Hash Urls而不是HTML 5路由{ provide: LocationStrategy,Useclass : hashllocationstrategy },]只要在HTML模板和router.navigate()中使用链接URL在routerLink中,Angular开关将自动在两种模式之间切换。

在HTML中使用routerLink='/相册'/链接来使用:router . navigate(['/相册',相册. id]) HTML5路由代码

HTML5路由使用了一种更复杂的方法——它使用HTML5的Pushstate API来控制客户端路由和管理地址栏显示。

这种方法的优点是HTML5 API相对容易操作,使用标准的非扩展路由约定。使用Web应用和API时,URL更简单,更容易控制。

但是,HTML5路由需要服务器的明确支持,才能正确理解哪些路由是服务器路由,哪些是客户路由。

服务器没有处理HTML5路由问题

问题是HTML5客户端路由与服务器路由无法区分。

http://localhost :4200/相册可以轻松使用客户端URL作为服务器URL。当在客户端完全导航时,HTML5路由工作正常——当特定路由被激活时,应用程序可以拦截导航并路由到相应的客户端页面。

如果您使用深层链接导航到客户端驱动的应用程序,然后为页面添加书签,然后使用网址导航回页面,或者刷新当前活动的页面,则会弹出一个问题。在这两种情况下,当浏览器请求路由时,客户端应用程序不会运行,因此浏览器会从服务器请求路由URL。但是,默认情况下,不会设置处理/相册路线,因此您会收到一个错误。

如果您在ASP.NET核心应用程序中没有对HTML5路由设置进行任何特殊处理,您将在应用程序中打开一个错误页面,或者从红隼中选择此默认显示:

图1-未处理的客户端路由生成服务器错误

修复服务器上的客户端路由

那么如何解决这个问题呢?

客户端SPA应用程序通常有一个或几个静态页面来启动应用程序。对于一个典型的Angular应用程序,这个页面是index.html启动应用程序和启动客户端路由。大多数框架都足够聪明,能够在启动时检查当前路由,并移动到第一个访问请求的路由。

如果客户端路由是从书签、链接或完全刷新触发到服务器的,则需要提供index.html并保持原始URL不变。

然后,客户端应用程序会自己启动,内部路由会启动,希望把你扔回到书签/刷新的位置。

从服务器提供Index.html

对于这项工作,您需要确保服务器只提供服务器负责的内容。

有几种方法可以做到这一点:

主机服务器网址重写处理ASP.NET核心应用程序中客户端路由主机网络服务器上的网址重写

如果您在主流Web服务器上运行ASP.NET核心(或ASP.NET)应用程序,最简单有效的解决方案是重写客户端URL,并为index.html给出的URL提供内容。

在IIS上,您可以使用IIS重写模块来执行此操作。我最近在一篇博客文章中更详细地介绍了这一点:

ASP.NET核心应用程序的IIS重写规则,但以下是相关的IIS重写规则:

重写规则!-确保您有一个base href='/' rel=' external no follow '/标记来修复根路径,否则所有相关链接将在重写时断开-规则名称=' AngularJS-Html5-Roads '停止处理='true '匹配url='。*/conditions logical grouping=' matcheall ' add input=' { REQUEST _ FILENAME } ' matchType=' IsFile ' invalice=' true '/add input=' { REQUEST _ FILENAME } ' matchType=' is directory ' invalice=' true '/add input=' { REQUEST _ URI } ' pattern=' API/' invalice=' true '/conditions action type=' Rewrite ' URL=' wwwroot/> index . html '/rule/rules/Rewrite您可以从以下任意位置安装UrlRewrite模块:

虫火谷在微软下载网站上安装urlRewrite Web平台安装程序如果你在Linux上运行Docker和nginX或者Apache,在那里可以使用类似的重写选项。

让ASP.NET核心处理客户端路由

如前所述,我通常使用像IIS或nginX这样的前端Web服务器来处理重定向,但通常在测试或内部应用程序时,我只需要Kestrel直接为应用程序提供服务。如果让红隼直接处理HTTP流量,需要用ASP.NET核心代码处理客户端路由。

捕获所有应用程序。运行()处理程序

有许多可用的方法,但是我在Startup类的Configure()方法中使用了一个非常简单的备份处理程序,找到了处理客户端路由的最简单方法:

//设置您使用UseMvc()使用的任何路由//如果您只使用属性路由,您可能不需要在这里设置任何路由//!app。UseMvc(routes={ routes。MapRoute(name: 'default ',template : ' { controller=Home }/{ action=Index }/{ id?}');});//处理客户端路由。运行(异步(上下文)={上下文。响应. ContentType=' text/html ';等待上下文。响应。发送文件异步(路径。合并(env。WebRootPath,' index . html ');});关键是那个应用。Run()是路由管道末端的中间件处理程序。如果服务器端路由找不到匹配的路由,通用处理程序将启动。

上面的代码是你能做的最简单的事情,只需将内容发送到index.html客户端即可。如果您有多个静态页面和SPA孤岛,您可以添加额外的逻辑来尝试确定需要加载哪些页面。

请注意,内容不会重定向到,而是作为嵌入流发送到现有的网址请求,因此用户请求的网址保持不变。这确保了当用户请求http://localhost :4200/相册时,您会返回到该客户端页面,而不是index.html。

捕获所有路由处理程序

另一种方法是使用在路由定义中最后定义的所有捕获的MVC路由处理程序。这基本上是拾取您的MVC路由配置无法处理的任何URL,然后将其路由到您指定的路由。

使用包罗万象的处理程序来设置您的MVC路由,并将此代码放在启动类的Configure()方法中:

app。UseMvc(routes={ //默认路由加上任何其他自定义路由)。MapRoute(name: 'default ',template : ' { controller=Home }/{ action=Index }/{ id?}');//捕获所有路由-捕获任何没有被其他路由捕获的路由。MapRoute(name: 'catch-all ',template : ' { URL } ',default s 3360 new { controller=' AlbumViewerApi ',action=' redirectndex ' });});然后做完全相同的事情。中间件处理程序使用:index.html使用以下代码将内容流式传输到客户端:

//我们需要为base path public IHostingEnvironment hostingev { get;} public albumviewerpicontroller(ihostingenvironmentenv){ hostingev=env;}[HttpGet]public IActionResult redirectndex(){返回新的PhysicalFileResult(路径。联合收割机。WebRootPath,' index.html '),new MediaTypeHeaderValue(' text/html ');}全面路线不使用属性路线

确保您为回退路由指定的路由没有分配属性路由。当我昨天检查它时,直到我[Route(' API/redirectndex ')]从控制器的操作中删除了所有这些工作,我才能得到一个全面的路线。

水疗服务

水疗服务提供了另一个选择,路线。MapSpaFallbackRoute()。虽然我自己没有尝试过,但是如果你已经在ASP.NET Core应用中使用了Spa服务,那么实现这个功能可能是一个简单的方法,包括对服务器预渲染的潜在支持。

概述

HTML5路由为客户端应用程序提供了一个干净的URL,但是它的价格必须得到服务器的支持才能正常工作。在主机Web服务器中使用重写规则或直接在Kestrel的中间件管道或自定义路由处理程序中设置它们并不难,但您必须确保将此功能显式添加到您创建的每个ASP.NET应用程序中。

虽然旧的Hash Bang路由看起来不那么干净,但它们工作正常,不需要任何服务器支持。对于非公共应用程序或需要支持古代浏览器的应用程序,散列状态行仍然是一种在没有服务器支持的情况下提供路由的可行方法。

最后,如果您使用的是完整的Web服务器,那么URL重写是处理由non-ASP.NET内核后端直接处理的非API内容的最干净、最有效的方法。

摘要

以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。

版权声明:如何应对ASP.NET芯HTML5客户端路由回退问题是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。