• 使用aspnetcore前后端分离开发,你一定要知道这个


    前言

    用过Vue单页面应用开发的,一定都知道Vue-router这个路由组件,它支持hashhistory两种模式。

    HTML5 History 模式

    vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

    如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

    const router = new VueRouter({
      mode: 'history',
      routes: [...]
    })
    

    当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!
    不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。

    所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

    aspnetcore使用Vuerouter history模式如何生产部署

    今天我们的目的就是如何使用history模式,让url地址更加简洁美观,为了更完整的演示,从头手把手演示一遍。

    创建vue项目

    首先安装nodejs,然后执行下面的npm命令创建vue3项目,跟着提示选择是或否即可完成项目的创建。本次创建的项目名称为vue-project

    npm init vue@3
    

    image.png

    创建aspnetcore的webapi项目

    如下图选择ASP.Net Core WebApi项目,项目名称为TestHistory,目录选择和上面Vue项目同属一个文件夹下。
    image.png

    配置History模式

    配置前端

    vscode打开前端项目,找到router配置
    image.png
    由于这里创建的是Vue3项目模板,模板自动配置好的vuerouter4,
    其实下面这种是一样的。详情参考,

    const router = new VueRouter({
      mode: 'history',
      routes: [...]
    })
    

    如果要使用hash模式,则使用createWebHashHistory函数创建。

    配置后端

    如果我们的前端和后端用的是同一个域名,也就是部署在同一个目录下,则应该将前端编译后的Html页面使用aspnetcore的静态资源进行托管,而不是直接放到根目录下。
    后端首先要添加app.UseStaticFiles();以支持静态资源托管,然后创建该中间件默认的静态资源文件目录wwwroot

    部署

    将webapi项目发布到本地
    image.png
    vue项目执行npm run build编译前端代码,将dist目录下的文件拷贝到到webapi发布后的wwwroot目录下,

    image.png

    IIS新建一个站点,这里使用8080端口
    image.png
    别忘记安装Hosting Bundle

    image.png

    如果一切顺利,打开http://localhost:8080你应该会看到这个页面。

    image.png
    点击about还会显示下面这个页面,而且地址是http://localhost:8080/about,这不就是history模式的效果吗!
    image.png
    什么都没做,效果就达到了?

    别急的得意,在http://localhost:8080/about这个地址下,刷新下网页试试。
    image.png
    卧槽,404了。

    先解释下为什么会这样,当你访问http://localhost:8080时由于iis默认是设置了默认文档

    image.png

    image.png
    当找不到你请求的资源时,它会尝试检查目录下的默认文档是否存在,按先后顺序检查,发现存在index.html所以就返回浏览器了,所以能够正常显示;当你点击about时,其实只是触发了页面的一个事件,页面有变化,url也变化了,但浏览器压根没刷新。当你手动刷新http://localhost:8080/about时,就向后端发起这个地址的Get请求,很明显,我们没有写任何Controller来匹配这个路由,wwwroot目录下也不存在about/index.html当然返回404了。

    如何配置history模式,而不导致404

    Vuerouter官方文档给出了部分后端服务器的配置方式 后端配置例子
    这里只展示aspnetcore常用的服务器

    nginx

    location / {
      try_files $uri $uri/ /index.html;
    }
    

    Internet Information Services (IIS)

    1. 安装 IIS UrlRewrite(opens new window)
    2. 在你的网站根目录中创建一个 web.config 文件,内容如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
        <rewrite>
          <rules>
            <rule name="Handle History Mode and custom 404/500" stopProcessing="true">
              <match url="(.*)" />
              <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
              </conditions>
              <action type="Rewrite" url="/" />
            </rule>
          </rules>
        </rewrite>
      </system.webServer>
    </configuration>
    

    nginx的由于没有环境,没有测试,应该没问题,配置也比较简单。
    iis的根据文档做一遍,UrlRewrite可以理解为是一个中间件,会对请求拦截,对符合规则的url进行路径重写,可行。

    当然我要做的不是上面的任何一种,因为我们的站点可能会部署到各种各样的服务器,每次换服务器都需要不同的配置来实现,很繁琐,既然我们aspnetcore拥有强大的中间件系统,为什么不让aspnetcore来做这件事呢,不再依赖不同服务器的配置方案,实现一次编码,到处运行,在之前的文章中有介绍过如何处理404 《ASP.NETCore统一处理404错误都有哪些方式?》
    那我们就在404的处理逻辑里实现其实就好了。

    直接上代码

    app.MapFallback(async (context) =>
    {
        var phpath = Path.Join(app.Environment.WebRootPath, context.Request.Path);
        var name = Path.Combine(Path.GetDirectoryName(phpath)!, "index.html");
        if (File.Exists(name))
        {
            context.Response.StatusCode = 200;
            await context.Response.SendFileAsync(name);
        }
    });
    

    1.当进入404处理逻辑时,首先拼接访问路径
    2.检查访问的路径所属的文件夹下是否存在index.html文件
    3.当文件存在,则修改响应码,返回该文件。
    4.不存在,什么也不干(这里其实可以做个友好提示页面)。
    重新发布,测试,不管如何刷新,都能正常显示了。

    源码

    Github上获取:https://github.com/SpringHgui/TestHistory


    __EOF__

  • 本文作者: Gui.H
  • 本文链接: https://www.cnblogs.com/springhgui/p/16177101.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    如何用看板工具做轻量级项目管理
    亚马逊云科技在天津设立智能制造数字化赋能中心
    【adb错误修复】adb version(39) doesn‘t match the client(40),killing...
    Python常见面试题
    Linux代码初试__进度条
    小学期-中期总结报告
    Marked.js让您的文档编辑更加轻松自如!
    分布式训练 最小化部署docker swarm + docker-compose落地方案
    05_对象性能模式
    RabbitMQ配置文件_修改RabbitMQ MQTT的1883端口
  • 原文地址:https://www.cnblogs.com/springhgui/p/16177101.html