本文主要解决 vue 项目使用 History 模式发布到服务器 Nginx 上刷新页面 404 问题.(由于每个项目的情况都不尽相同, 本方案已经完美解决本在所使用项目, 具体情况可能还需要修改.)
1. 项目背景分析
本人是 Java 后台开发, Vue 其实使用也没有多久, 只能说简单了解. 发现问题的时候其实也一头雾水, 第一思想就是百度看别人的思路.
1.1 查看项目打包后文件
首先看看项目打包后文件内容, 看看有没有什么能突破的地方. 文件目录如下:
打眼一看可以发现, 主要的可能就是这个 index.html 文件, 内容如下:
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="utf-8">
- <title>
- 系统管理
- </title>
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
- <link rel="shortcut icon" type="image/x-icon" href="logo.png">
- <link rel="shortcut icon" href="logo.png">
- </head>
- <body>
- <div id="app">
- </div>
- <script type="text/javascript" src="manifest.js?89b5083667173048a500">
- </script>
- <script type="text/javascript" src="vendor.js?9eae337435ee1b63d5cd">
- </script>
- <script type="text/javascript" src="index.js?38915745c7ed8b9143db">
- </script>
- </body>
- </HTML>
1. 在之前百度的时候看到了一个信息, 就是引入 JS 文件使用 scr 的时候, 如果前面带 / 是绝对路径, 在思考是不是这个问题.
2. 百度的时候大部分信息都是说修改 Nginx 配置文件.
2. 问题解决
既然大致思路都有了, 那么就开始尝试去解决一下.
2.1 更改 Vue 打包配置文件
修改 webpack.config.JS 文件, 这个是 Vue-cli 打包文件配置, 使其打包后让 index.HTML 文件引用路径为绝对路径. webpack.config.JS 内容如下 (每个项目打包配置均不同, 这个配置仅仅是我使用的项目):
- const resolve = require('path').resolve
- const webpack = require('webpack')
- const HtmlWebpackPlugin = require('html-webpack-plugin')
- const url = require('url')
- const publicPath = '/'
- module.exports = (options = {}) => ({
- entry: {
- vendor: './src/vendor',
- index: './src/main.js'
- },
- output: {
- path: resolve(__dirname, 'dist'),
- filename: options.dev ? '[name].js' : '[name].js?[chunkhash]',
- chunkFilename: '[id].js?[chunkhash]',
- publicPath: options.dev ? '/assets/' : publicPath
- },
- module: {
- rules: [{
- test: /\.vue$/,
- use: ['vue-loader']
- },
- {
- test: /\.JS$/,
- use: ['babel-loader'],
- exclude: /node_modules/
- },
- {
- test: /\.CSS$/,
- use: ['style-loader', 'css-loader', 'postcss-loader']
- },
- {
- test: /\.(PNG|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,
- use: [{
- loader: 'url-loader',
- options: {
- limit: 10000
- }
- }]
- }
- ]
- },
- plugins: [
- new webpack.optimize.CommonsChunkPlugin({
- names: ['vendor', 'manifest']
- }),
- new HtmlWebpackPlugin({
- template: 'src/index.html',
- favicon: 'src/logo.png'
- })
- ],
- resolve: {
- alias: {
- '~': resolve(__dirname, 'src')
- },
- extensions: ['.js', '.vue', '.json', '.css']
- },
- devServer: {
- host: '127.0.0.1',
- port: 8010,
- proxy: {
- '/api/': {
- target: 'http://127.0.0.1:8080',
- changeOrigin: true,
- pathRewrite: {
- '^/api': ''
- }
- }
- },
- historyApiFallback: {
- index: url.parse(options.dev ? '/assets/' : publicPath).pathname
- }
- },
- devtool: options.dev ? '#eval-source-map' : '#source-map'
- })
再次打包后, 查看 index.HTML, 内容如下:
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="utf-8">
- <title>
- 系统管理
- </title>
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
- <link rel="shortcut icon" type="image/x-icon" href="logo.png">
- <link rel="shortcut icon" href="/logo.png">
- </head>
- <body>
- <div id="app">
- </div>
- <script type="text/javascript" src="/manifest.js?f7d4b2121bc37e262877">
- </script>
- <script type="text/javascript" src="/vendor.js?9eae337435ee1b63d5cd">
- </script>
- <script type="text/javascript" src="/index.js?51954197166dd938b54e">
- </script>
- </body>
- </HTML>
从 index.HTML 可以看出已经变成了绝对路径.
2.2 修改 Nginx 配置
修改 nginx.conf 配置文件, 代码如下:
- worker_processes 1;
- events {
- worker_connections 1024;
- }
- http {
- include mime.types;
- default_type application/octet-stream;
- sendfile on;
- keepalive_timeout 65;
- server {
- listen 80;
- server_name localhost;
- ## 指向 vue 打包后文件位置
- root /opt/nginx/dist/;
- ## 拦截根请求, 例如 http://localhost
- location / {
- try_files $uri $uri/ /index.HTML;
- }
- ## 拦截带有 tms-monitor 的请求, 例如 http://localhost/tms-monitor/admin
- location ^~/tms-monitor{
- if (!-e $request_filename) {
- rewrite ^/(.*) /index.HTML last;
- break;
- }
- }
- #error_page 500 502 503 504 /50x.HTML;
- location = /50x.HTML {
- root HTML;
- }
- }
- }
3. 总结
上述配置完成后, 打包 Vue 项目, 重启 Nginx 再次刷新就不会在有 404 的现象了.(再次申明: 以上只是针对本人所在的项目, 不一定使用所有情况.)
来源: https://juejin.im/post/5bd7c4196fb9a05cd45730b5