Skip to content
🗂️ 文章分类: 服务器  
🏷️ 文章标签: Nginx  
📝 文章创建时间: 2023-02-14
🔥 文章最后更新时间:2026-02-06

[toc]

nginx部署页面笔记

nginx 是一个高性能的 Web 服务器和反向代理服务器,常用于部署静态页面、动态应用、负载均衡等场景。

作为开发者,我们常遇到「本地开发正常,Nginx 部署后页面刷新 404、路由跳转异常」的问题。

核心原因往往是前端路由的 Hash/History 模式,与 Nginx 静态资源配置不匹配。

SPA应用(单页面应用) 介绍

什么是SPA应用?

SPA应用是指只有一个HTML页面的应用,所有的页面内容都是通过Ajax动态加载的。SPA应用的优势在于用户体验好,页面切换快,因为不需要重新加载整个页面。

用户在与SPA应用交互时,不会导致页面刷新。相反,它会通过动态加载内容来更新页面的不同部分。

SPA应用通常由以下几个部分组成

  • 前端代码:负责处理用户交互、渲染页面和与后端通信。
  • 后端代码:负责处理业务逻辑、数据存储和提供 API 接口。
  • 数据库:用于存储应用程序的数据。

SPA应用的优势在于

  • 提供流畅的用户体验,无需页面刷新。
  • 减少了对服务器的请求次数,提高了应用程序的性能。
  • 可以在不同设备上运行,包括移动设备和桌面设备。

单页面应用的目录结构

使用前端打包工具(如 Webpack、Rollup 等)可以将单页面应用(SPA)代码打包成静态文件,这些文件通常存储在项目根目录下的 distbuild 文件夹中。

目录结构大致如下

dist/  # 打包输出目录
├── index.html  # 入口文件(核心)
├── static/     # 静态资源(JS/CSS/图片)
│   ├── js/
│   └── css/
└── favicon.ico   # 网站图标(可选)

单页面应用的两种模式(Hash模式和History模式)

在单页面应用(SPA)中,通过改变 URL 而不重新请求页面,实现视图切换。Hash 和 History 是实现这一目标的两种核心方式,也是 Nginx 配置差异的根源。

Hash模式(URL 带 #)

核心原理

URL 中 # 后的部分(如 https://xxx.com/#/home中的/home)被称为「哈希值,路由」,浏览器不会将哈希值发送给服务器,仅在前端解析。

特点

✅ 无需服务器配置,部署零成本; ❌ URL 带 #,不够美观,部分场景(如微信分享)可能解析异常; ✅ 刷新页面不会触发服务器请求,仅前端解析哈希值,不会 404。

History模式(URL 不带 #)

核心原理

基于 HTML5 History API,通过 pushState/replaceState 来改变 URL,URL 与普通网页一致(如 https://xxx.com/home),刷新时会向服务器发送「该路径」的请求。

特点

URL 简洁美观,符合用户习惯; ❌ 依赖服务器配置,刷新页面会请求服务器,若配置不当直接 404; ✅ 支持 SEO 优化,Hash 模式的哈希值不会被搜索引擎抓取。

Nginx部署单页面应用(SPA)的配置

无论哪种模式,Nginx 部署静态页面的核心是「精准指向前端打包后的静态文件目录」

Hash 模式:Nginx 配置 (无路径前缀)

因为 Hash 模式的哈希值不会发送给服务器,Nginx 只需「托管静态文件」即可,无需额外配置路由。

nginx
# nginx 配置文件
server {
    listen 8888;
    server_name your-server-ip;  # 服务器IP/域名

    # 核心:指向打包后的dist目录(index.html所在目录)
    root /usr/local/nginx/html/dist;
    index index.html;  # 默认首页

    # 静态资源缓存优化(可选,提升加载速度)
    location ~* \.(js|css|png|jpg|gif)$ {
        expires 7d;  # 缓存7天
        add_header Cache-Control "public, max-age=604800";
    }

    # 安全:禁止访问隐藏文件(如.git/.env)
    location ~ /\. {
        deny all;
    }
}

验证方式:

  1. 访问 http://your-server-ip:8888/,确认能正常加载 index.html
  2. 刷新页面,确认仍能正常加载内容(无 404)。
  3. 尝试访问 http://your-server-ip:8888/#/xxx,确认能正常加载 xxx 路由对应的内容。

Hash 模式:Nginx 配置 (带路径前缀)

当我们想将多个SPA应用部署在服务器上,然后通过多个路径前缀区分不同的应用(如 http://服务器IP/proj1/#/homehttp://服务器IP/proj2/#/home)。

假设有1个SPA应用,路径前缀是 proj1。

① SPA应用打包为静态页面的时候,需要指定全局路由路径(base)为 /proj1/

js
// router/index.js
const router = new VueRouter({
  mode: 'hash',
  base: '/proj1/', // 匹配Nginx的路径前缀
  routes: [...]
});

这段的意思是,SPA应用的路由路径前缀为 /proj1/,即访问该SPA应用的路由路径都需要以 /proj1/ 开头。

② 配置Nginx

nginx
server {
    listen 8888;
    server_name your-server-ip;

    # 项目1:路径前缀 /proj1
    location /proj1/ {
        # root指向dist的上级目录(而非dist本身)
        root /usr/local/nginx/html;
        index index.html;
        # Hash模式无需try_files,因为服务器仅接收/proj1/请求
    }
    # .........
}

配置说明:

  • 当访问 http://your-server-ip:8888/proj1/#/ 时,Nginx 会指向 /usr/local/nginx/html/proj1/目录下的 index.html 文件。
  • 若直接配置 root /usr/local/nginx/html/proj1,Nginx 会查找 /usr/local/nginx/html/proj1/proj1/目录下的index.html文件(多一层前缀,导致 404)。

总结:root 路径 + location 路径 = Nginx 实际查找路径 = 静态文件实际存放的路径

③ 验证方式

访问 http://服务器IP:8888/proj1/#/home,刷新页面。若正常访问,则表示服务器仅请求 /proj1/。

History 模式:Nginx 配置 (无路径前缀)

History 模式的核心问题是「刷新页面时,浏览器会请求 http://服务器IP:端口/xxxx,但服务器没有 xxxx 这个文件」。因此需要 Nginx 配置 try_files,将所有路由请求重定向到 index.html,由前端路由解析。

nginx
server {
    listen 8888;
    server_name your-server-ip;

    root /usr/local/nginx/html/dist;
    index index.html;

    # 核心:解决History模式刷新404
    location / {
        # 按顺序查找:当前路径文件 → 当前路径目录 → 跳转到index.html
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存(同Hash模式)
    location ~* \.(js|css|png|jpg|gif)$ {
        expires 7d;
        add_header Cache-Control "public, max-age=604800";
    }

    # 安全:禁止访问隐藏文件(如.git/.env)
    location ~ /\. {
        deny all;
    }
}

History 模式:Nginx 配置 (带路径前缀)

当我们想将多个SPA应用部署在服务器上,然后通过多个路径前缀区分不同的应用(如 http://服务器IP/proj1/#/homehttp://服务器IP/proj2/#/home)。

假设有1个SPA应用,路径前缀是 proj1。

① SPA应用打包为静态页面的时候,需要指定全局路由路径(base)为 /proj1/

js
// router/index.js
const router = new VueRouter({
  mode: 'history',
  base: '/proj1/', // 匹配Nginx的路径前缀
  routes: [...]
});

注意:打包时需同步配置静态文件的 publicPath: '/proj1/',否则静态资源会请求根路径导致 404。

② Nginx 配置

nginx
server {
    listen 8888;
    server_name your-server-ip;

    # 项目1:路径前缀 /proj1
    location /proj1/ {
        root /usr/local/nginx/html;
        index index.html;

        # 核心:兜底路径必须加前缀/proj1/,否则会跳转到根目录的index.html
        try_files $uri $uri/ /proj1/index.html;
    }

    # ..........
}

③ 验证方式

访问 http://服务器IP:8888/proj1/#/home,刷新页面。若正常访问,则表示服务器仅请求 /proj1/。

4种区别总结

场景URL 示例服务器请求路径前端核心配置Nginx 核心配置关键区别
Hash(无前缀)http://ip/#/homehttp://ip/无(默认根路径)仅 root + index无需 try_files,服务器无感路由
History(无前缀)http://ip/homehttp://ip/homebase: '/'root + index + try_files /index.html需 try_files 兜底到根 index.html
Hash(带前缀 /proj1)http://ip/proj1/#/homehttp://ip/proj1/base: '/proj1/'root 指向上级目录 + location /proj1/无需 try_files,仅适配前缀路径
History(带前缀 /proj1)http://ip/proj1/homehttp://ip/proj1/homebase: '/proj1/'root 指向上级目录 + try_files /proj1/index.html需 try_files 兜底到前缀 index.html