javascript - NGinx 上的 VueJS 路由器历史模式
问题描述
我一直在研究,我发现了许多与我的问题相似的问题。
我有一个 docker-compose 在 Digital Ocean 上运行,带有 NGinx、VueJS 和静态登陆页面。
在我用表格创建新路线之前,一切都很好。这条路线将通过一个通过电子邮件发送给客户的链接访问,该链接带有一个 ID 以识别谁正在访问该页面。
结构示例:
https://example.org -> 登陆页面
https://example.org/quiz -> 我的 vuejs 应用程序
https://example.org/quiz/confirmation/some-customer-id -> 我在 vuejs 上的路由器
VueJS 配置:
const webpack = require('webpack')
module.exports = {
devServer: {
port: '8092',
},
publicPath: '/quiz/',
runtimeCompiler: true,
configureWebpack: {
entry: {
main: path.resolve(__dirname, 'src/main.js'),
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: process.env.production ? '[name].[contenthash:8].js' : '[name].[hash].js',
},
plugins: [
new webpack.HashedModuleIdsPlugin(), // so that file hashes don't change unexpectedly
],
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
// npm package names are URL-safe, but some servers don't like @ symbols
return `npm.${packageName.replace('@', '')}`
},
},
},
},
},
},
lintOnSave: true,
css: {
loaderOptions: {
sass: {
prependData: `
@import "@/assets/scss/app-custom.scss";
`,
},
},
},
chainWebpack: (config) => {
config.plugins.delete('prefetch')
},
}
VueJS 路由器配置:
import VueRouter from 'vue-router'
import {Trans} from '@/plugins/translation'
import {ROUTER_NAME} from "./names";
const Quiz = () => import(/* webpackChunkName: "Quiz" */ '@/views/Quiz.vue')
const QuizResults = () => import(/* webpackChunkName: "QuizResults" */ '@/views/QuizResults.vue')
const QuizSuccess = () => import(/* webpackChunkName: "QuizSuccess" */ '@/views/QuizSuccess.vue')
const QuizConfirmation = () => import(/* webpackChunkName: "QuizResults" */ '@/views/QuizConfirmation.vue')
Vue.use(VueRouter)
const routes = [
{
path: '/:lang',
component: {
template: '<router-view></router-view>',
},
beforeEnter: Trans.routeMiddleware,
children: [
{
path: '/',
name: ROUTER_NAME.QUIZ,
component: Quiz
}, {
path: '/results',
name: ROUTER_NAME.QUIZ_RESULTS,
component: QuizResults
}, {
path: '/success',
name: ROUTER_NAME.QUIZ_SUCCESS,
component: QuizSuccess
}
]
},
{
path: '/confirmation/:quizId',
name: ROUTER_NAME.QUIZ_CONFIRMATION,
component: QuizConfirmation,
props: true
},
{
// Redirect user to supported lang version.
path: '*',
redirect(to) {
return Trans.defaultLanguage
}
}
]
const router = new VueRouter({
mode: 'history',
base: '/quiz/',
routes
})
export default router
NGinx 配置:
listen 80;
listen [::]:80;
server_name example.org www.example.org;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
location / {
rewrite ^ https://$host$request_uri? permanent;
}
location /quiz {
rewrite ^ https://$host$request_uri? permanent;
}
location /shop {
rewrite ^ https://$host$request_uri? permanent;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.org www.example.org;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/mysite.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.org/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
location / {
try_files $uri $uri/ =404;
}
location /quiz {
alias /var/www/html/quiz;
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
try_files $uri $uri/ /quiz/index.html;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
}
我已经关注了所有可用的文档和 stackoverflow 问题,但它们都不起作用。
基本上,当我单击链接https://example.org/quiz/confirmation/some-customer-id时,该站点将重定向到配置中/quiz/index.html
定义的位置location /quiz
:
location /quiz {
alias /var/www/html/quiz;
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
try_files $uri $uri/ /quiz/index.html;
}
你知道我能做些什么来解决这个问题吗?如果您需要更多信息,请告诉我。
多谢你们。
解决方案
使用嵌套路由时,您必须删除子路径中的斜杠“/”,
所以你的 vue-router 配置将是这样的:
const routes = [
{
path: '/:lang',
component: {
template: '<router-view></router-view>',
},
beforeEnter: Trans.routeMiddleware,
children: [
{
path: '',
name: ROUTER_NAME.QUIZ,
component: Quiz
}, {
path: 'results',
name: ROUTER_NAME.QUIZ_RESULTS,
component: QuizResults
}, {
path: 'success',
name: ROUTER_NAME.QUIZ_SUCCESS,
component: QuizSuccess
}
]
},
{
path: '/confirmation/:quizId',
name: ROUTER_NAME.QUIZ_CONFIRMATION,
component: QuizConfirmation,
props: true
},
{
// Redirect user to supported lang version.
path: '*',
redirect(to) {
return Trans.defaultLanguage
}
}
]
你可以在这里查看 vue-router 文档。
推荐阅读
- swift - 按钮文本未使用 @state 从其自己的操作中更新
- c - 写一个for循环中断程序(出乎意料)
- javascript - JS - 防止追加被多次添加
- bash - 如何修复 Linux Bash 中的 PATH 识别
- python - Flask URL 路由编码问题
- sql - .NET SQL Server 按名称和 IP 连接的行为不同
- c++ - 布尔运算符 Arduino
- javascript - 错误:监听 EADDRINUSE:地址已在使用 :::3000
- css - Material UI - 为 SVG 设置颜色
- uml - 如何在 Visual Paradigm 中拆分序列图