使用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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然!在ASP.NET Core 6中,你可以使用Web API特性路由和前后端调用分离技术来构建灵活的Web API。下面是一个示例,演示如何实现这些功能。 首先,创建一个新的ASP.NET Core 6 Web API项目。在Visual Studio 2022中,选择"创建新项目",然后选择"ASP.NET Core Web API"模板,并点击"下一步"。 接着,给你的项目命名,并选择合适的位置进行保存。点击"创建"。 默认情况下,ASP.NET Core 6使用控制器类名作为路由的一部分。为了使路由更加灵活,我们可以使用Web API特性路由。 打开`Controllers`文件夹,创建一个新的控制器,命名为`ValuesController.cs`。在控制器中,添加以下代码: ```csharp using Microsoft.AspNetCore.Mvc; namespace YourProject.Controllers { [ApiController] [Route("api/[controller]")] public class ValuesController : ControllerBase { [HttpGet] public IActionResult Get() { return Ok(new string[] { "value1", "value2" }); } [HttpGet("{id}")] public IActionResult Get(int id) { return Ok($"value{id}"); } [HttpPost] public IActionResult Post([FromBody] string value) { // 处理POST请求 return Ok(value); } [HttpPut("{id}")] public IActionResult Put(int id, [FromBody] string value) { // 处理PUT请求 return Ok(value); } [HttpDelete("{id}")] public IActionResult Delete(int id) { // 处理DELETE请求 return Ok($"Deleted value{id}"); } } } ``` 在上述代码中,我们使用`[ApiController]`特性来指示控制器是一个Web API控制器,并使用`[Route("api/[controller]")]`特性来指定路由模板。这里的`[controller]`将被替换为控制器类名的小写形式(即"values")。 在控制器中,我们定义了五个动作方法:`Get`、`Get(id)`、`Post`、`Put(id)`和`Delete(id)`。这些方法分别对应于HTTP的GET、POST、PUT和DELETE请求,并通过`HttpGet`、`HttpPost`、`HttpPut`和`HttpDelete`特性进行标记。 在这个示例中,我们简单地返回一些字符串作为响应。你可以根据自己的需求在这些方法中添加逻辑。 接下来,我们需要实现前后端调用分离技术。在这里,我们可以使用JavaScript的Axios库来发起HTTP请求。 在wwwroot文件夹下创建一个新的文件夹,命名为"js"。在该文件夹中创建一个新的JavaScript文件,命名为"api.js",并添加以下代码: ```javascript import axios from 'axios'; const baseUrl = '/api/values'; // Web API的基本URL export const getValues = async () => { const response = await axios.get(baseUrl); return response.data; }; export const getValue = async (id) => { const response = await axios.get(`${baseUrl}/${id}`); return response.data; }; export const postValue = async (value) => { const response = await axios.post(baseUrl, value); return response.data; }; export const putValue = async (id, value) => { const response = await axios.put(`${baseUrl}/${id}`, value); return response.data; }; export const deleteValue = async (id) => { const response = await axios.delete(`${baseUrl}/${id}`); return response.data; }; ``` 在上述代码中,我们定义了几个函数,分别对应于GET、POST、PUT和DELETE请求。这些函数使用Axios库来发送HTTP请求,并返回响应数据。 最后,在HTML文件中引入这个JavaScript文件,并调用相应的函数来实现前后端交互。 这就是一个使用ASP.NET Core 6的Web API特性路由和前后端调用分离技术的示例。希望对你有帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值