Django+Vue 解决URL访问与刷新导致404的问题

问题分析

要想知道这个问题为什么会产生,首先还是应该搞明白单页面应用与Vue-router的本质:

什么是单页面应用(SPA)
单页面应用(Single Page Web Application)的本质其实就是一个外壳页面加上不同的页面组件(也就是构成页面本体的不同片段)。与传统的多页面应用(MPA,Multiple Page Web Application)每次跳转都是一次HTTP请求不同,单页面应用的页面跳转只是页面的局部刷新——使用JavaScript等操作DOM的工具将页面的一部分显示或者隐藏,达到“看起来像是页面跳转了”的效果。

vue-router本来是使用“hash模式”(也就是url前面有个“#”,这个部分不改变页面就不会重新加载)的,但是为了美观和与我们以往的经验相同,可以使用“history模式”去掉这个“#”,这样我们看到的单页面应用的url就和多页面应用的url相差无几了。

正因为没有使用“hash模式”,所以url跟正常的多页面应用的url一模一样。当输入url、刷新页面时这个虚假的url也会被后端解析,但它的本质只是与页面不同组成部分之间的映射关系,所以肯定是不可能真正存在于服务器上的,被后端解析之后,返回404 Not Found也就不是奇怪的事情了。

解决方法

配置后端时,除了接口之外,无论我们请求什么,都返回原来的index.html就可以

from django.contrib import admin
from django.urls import path, re_path
from django.views.generic import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', TemplateView.as_view(template_name='index.html')),
    re_path(r'.*', TemplateView.as_view(template_name='index.html'))
]

这样做又会引来新的问题:无论我们访问什么都不返回404了。

这个问题也不难解决,开发一个专门的404组件,并且在vue-router里配置一下:在配置完所有的url之后,配置上这个404组件。