This article mainly solves the Vue project using History mode to publish to the server Nginx refresh page 404 problem. (Since the situation of each project is different, this solution has been perfectly solved for the project in use, the specific situation may need to be modified.)

1. Project background analysis

I am Java background development, Vue is actually not used for a long time, can only say a simple understanding. Found the problem is also confused, the first thought is Baidu to see other people’s ideas.

1.1 Viewing the Packaged project files

Start by looking at the document after the project is packaged to see if there are any breakthroughs. The file directories are as follows:

At first glance, the main one is probably this index.html file, which reads as follows:

<! DOCTYPE html> <html lang="en">

<head>
  <meta charset="utf-8"> <title> System management </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>
Copy the code

1. I saw a message in Baidu before, that is, when introducing JS files and using SCR, if/is the absolute path in front of it, I am wondering whether this is the problem.

2. Most of the information on Baidu is about modifying the Nginx configuration file.

2. Problem solving

Now that you have the general idea, start trying to solve it.

2.1 Changing the Vue packaging configuration File

Modify the webpack.config.js file, which is the vue-cli package file configuration, so that it is packed so that the index. HTML file reference path is an absolute path. Webpack.config.js looks like this (each project has a different packaging configuration, and this configuration is just the project I used) :

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'
})

Copy the code

Once you’ve packed it again, look at index.html, which looks like this:

<! DOCTYPE html> <html lang="en">

<head>
  <meta charset="utf-8"> <title> System management </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>
Copy the code

As you can see from index.html, it has become an absolute path.

2.2 Modifying Nginx Configuration

To modify the nginx.conf configuration file, run the following code:

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;
      ## points to the vue packed file location
      root /opt/nginx/dist/;

      ## Intercept the root request, for example http://localhost
      location / {
            try_files $uri $uri/ /index.html;
      }

      ## Intercept requests with TMS-monitor, such as 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; }}}Copy the code

3. Summary

After the above configuration is complete, package the Vue project, restart Nginx and refresh again. (Again: the above is for my project only and may not be used in all cases.)