TIP

系统默认使用Hash 历史模式,这种模式URL内会带有#号,当你有SEO需求或认为它不美观时,可以参考以下文档隐藏#号。
我们提供了Nuxt工程,该工程URL不含#号,推荐管理员后台无需隐藏#号,而用户端使用Nuxt工程即可

# 第一步:修改代码

找到web\src\router\index.ts文件,将createWebHashHistory修改为createWebHistory

原来的:

import { createRouter, createWebHashHistory } from 'vue-router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { staticRoutes } from '/@/router/static'
import { loading } from '/@/utils/loading'

const router = createRouter({
    history: createWebHashHistory(),
    routes: staticRoutes,
})

修改为:

import { createRouter, createWebHistory } from 'vue-router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { staticRoutes } from '/@/router/static'
import { loading } from '/@/utils/loading'

const router = createRouter({
    history: createWebHistory(),
    routes: staticRoutes,
})

此时,开发环境已经可以使用不带#号的URL进行访问了,但是在线上环境中,直接访问domain.com/user/login会提示404,这是因为没有适当的服务器配置,请继续参考下文进行配置。

# 第二步:配置服务器

以下服务器配置,已经包含ThinkPHP的伪静态规则,所以请注意,一旦配置就不再需要配置ThinkPHP的伪静态规则了。

# [ Nginx ] 配置

# Nginx站点配置文件
server {
    listen        80;
    server_name   ba.com;
    root   "D:/WWW/ba.com/public";

    # 找到 "/" 的代码块,没有则定义
    location / {

        # 将 index.html 放在第一位可以实现隐藏 index.html
        index index.html index.php error/index.html;

        # 这一段为 URL重写规则 请确保存在
        set $server 0;
        if ($request_uri ~* "server=1") {
            set $server 1;
        }
        if ($http_server) {
            set $server 1;
        }
        if ($server = 1) {
            rewrite  ^(.*)$  /index.php?s=/$1  last;
            break;
        }
        try_files $uri $uri/ /index.html;
        # 结束
    }

    # 已省略余下代码
}

# [ Apache ] 配置

  1. httpd.conf配置文件中加载了mod_rewrite.so模块
  2. 站点对应的conf文件中AllowOverride NoneNone改为All
  3. 把下面的内容保存为.htaccess文件放到应用入口文件的同级目录下(public目录
<IfModule mod_rewrite.c>
  Options +FollowSymlinks -Multiviews
  RewriteEngine On
  RewriteBase /

  RewriteRule ^index\.html$ - [L]
  RewriteRule ^index\.php$ - [L]

  RewriteCond %{QUERY_STRING} server=1 [OR,NC]
  RewriteCond %{HTTP:server} true
  RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

# [ IIS ] 配置

  1. 安装url-rewrite (opens new window)
  2. 站点根目录(public目录)建立web.Config文件,写入以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <!-- 服务端请检测 -->
                <rule name="BuildAdmin" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAny">
                        <add input="{QUERY_STRING}" pattern="server=1" ignoreCase="true" />
                        <add input="{HTTP_SERVER}" pattern="true" ignoreCase="true" />
                    </conditions>
                    <action type="Rewrite" url="index.php/{R:1}" appendQueryString="true" />
                </rule>
                <!-- 服务端请求检测结束 -->

                <!-- 前端请求检测-转到index.html -->
                <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>
        <!-- 默认文档配置,index.html排第一 -->
        <defaultDocument>
            <files>
                <clear />
                <add value="index.html" />
                <add value="index.php" />
                <add value="Default.htm" />
                <add value="Default.asp" />
                <add value="index.htm" />
                <add value="iisstart.htm" />
            </files>
        </defaultDocument>
    </system.webServer>
</configuration>

# 我曾对外分发带有#的链接

如何保证,以往带有#的链接在短时间内,依旧有效? 在web/src/App.vue文件内,获取当前url,如果带有hash进行跳转即可

onMounted(() => {
    iconfontInit()
    terminal.init()

    // 添加的检测 hash 代码
    if (window.location.hash) {
        window.location.href = window.location.hash.replace('#', '')
    }
    // 结束

    // Modules onMounted mark, Please do not remove.
})

# 允许跨域(如果有跨域需求)

通过以上的配置,OPTIONS请求不能再正常的被程序放行,可以额外增加允许OPTIONS请求的代码`

# [ Nginx ]配置

# 放行 OPTIONS(如果有跨域需求)
# 请将 if 代码块,合入到之前的 location / 代码块
location / {
    # ...
    if ($request_method ~* OPTIONS) {
        add_header Access-Control-Max-Age '86400';
        add_header Access-Control-Allow-Origin '*';
        add_header Access-Control-Allow-Headers '*';
        add_header Access-Control-Allow-Credentials 'true';
        add_header Access-Control-Allow-Methods 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
        return 204;
    }
    # ...
}