diff --git a/.env.production b/.env.production index f8ee73a..41d4531 100644 --- a/.env.production +++ b/.env.production @@ -1,5 +1,5 @@ # 生产环境API基础URL(根据实际情况选择) -VITE_API_BASE=http://192.140.164.137:18080 +VITE_API_BASE=https://2.uzi0.cc/api # 前端基础URL(用于生成分享链接) -VITE_BASE_URL=https://2.uzi0.cc/ \ No newline at end of file +VITE_BASE_URL=https://2.uzi0.cc \ No newline at end of file diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..a7ea763 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,71 @@ +# Vue SPA 部署指南 + +## 问题描述 + +当直接访问 `http://2.uzi0.cc/play?code=973F2YTE` 时出现404错误,但其他页面正常。这是典型的单页应用(SPA)部署问题。 + +## 原因分析 + +1. **开发环境**:Vite开发服务器自动处理路由回退 +2. **生产环境**:Web服务器尝试查找实际的 `/play` 文件,但这只是前端路由 + +## 解决方案 + +### 方案一:Nginx 配置(推荐) + +1. 使用项目根目录的 `nginx.conf` 文件 +2. 修改其中的 `root` 路径为实际部署路径 +3. 重新加载 Nginx 配置: +```bash +sudo nginx -t # 测试配置 +sudo nginx -s reload # 重新加载 +``` + +### 方案二:Apache 配置 + +1. 将 `apache.htaccess` 文件复制到 `dist` 目录下,重命名为 `.htaccess` +2. 确保 Apache 启用了 `mod_rewrite` 模块 + +### 方案三:Netlify 部署 + +1. 将 `_redirects` 文件复制到 `dist` 目录下 +2. 重新部署到 Netlify + +### 方案四:其他静态托管服务 + +对于其他静态托管服务,需要配置: +- 所有路由都回退到 `index.html` +- API 请求代理到 `http://192.140.164.137:18080` + +## 重新构建和部署 + +```bash +# 1. 重新构建项目 +npm run build + +# 2. 将构建文件部署到服务器 +# 确保 dist 目录下的所有文件都已上传 + +# 3. 配置 Web 服务器(选择上述方案之一) + +# 4. 测试访问 +# http://2.uzi0.cc/play?code=973F2YTE 应该能正常访问 +``` + +## 验证步骤 + +1. 直接访问:`http://2.uzi0.cc/play?code=973F2YTE` +2. 应该能看到游戏页面,而不是404错误 +3. 刷新页面应该仍然正常 +4. API 请求应该正常工作(无CORS错误) + +## 常见问题 + +### Q: 仍然出现404错误 +A: 检查Web服务器配置是否正确应用,确认配置文件路径和语法 + +### Q: API请求失败 +A: 检查代理配置,确认后端服务 `http://192.140.164.137:18080` 可访问 + +### Q: 静态资源加载失败 +A: 检查资源路径配置,确认 `base` 配置正确 diff --git a/_redirects b/_redirects new file mode 100644 index 0000000..f360379 --- /dev/null +++ b/_redirects @@ -0,0 +1,8 @@ +# Netlify _redirects 文件 +# 放置在 dist 目录下 + +# API 代理 +/api/* http://192.140.164.137:18080/:splat 200 + +# SPA 路由回退 +/* /index.html 200 diff --git a/apache.htaccess b/apache.htaccess new file mode 100644 index 0000000..d5f3c36 --- /dev/null +++ b/apache.htaccess @@ -0,0 +1,32 @@ +# Apache .htaccess 配置文件 +# 放置在 dist 目录下 +# 解决 Vue SPA 应用的路由问题 + + + RewriteEngine On + + # 处理预检请求 + RewriteCond %{REQUEST_METHOD} OPTIONS + RewriteRule ^(.*)$ $1 [R=200,L] + + # 静态资源直接访问 + RewriteCond %{REQUEST_FILENAME} -f + RewriteRule ^ - [L] + + # API请求代理到后端(需要配置虚拟主机) + RewriteCond %{REQUEST_URI} ^/api/ + RewriteRule ^api/(.*)$ http://192.140.164.137:18080/$1 [P,L] + + # SPA路由回退到index.html + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.html [L] + + +# CORS 头部设置 + + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" + Header always set Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" + Header always set Access-Control-Max-Age "1728000" + diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..bcc81cb --- /dev/null +++ b/nginx.conf @@ -0,0 +1,53 @@ +# Nginx 配置文件 +# 解决 Vue SPA 应用的路由问题 + +server { + listen 80; + server_name 2.uzi0.cc; + root /path/to/your/dist; # 修改为你的实际部署路径 + index index.html; + + # 处理静态资源 + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } + + # API代理 - 解决CORS问题 + location /api/ { + proxy_pass http://192.140.164.137:18080/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # CORS 头部 + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; + add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; + + # 处理预检请求 + if ($request_method = 'OPTIONS') { + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; + add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; + add_header Access-Control-Max-Age 1728000; + add_header Content-Type 'text/plain; charset=utf-8'; + add_header Content-Length 0; + return 204; + } + } + + # SPA 路由回退 - 关键配置 + location / { + try_files $uri $uri/ @fallback; + } + + location @fallback { + rewrite ^.*$ /index.html last; + } + + # 错误页面 + error_page 404 /index.html; +} diff --git a/vite.config.js b/vite.config.js index efb45a9..f1e8e51 100644 --- a/vite.config.js +++ b/vite.config.js @@ -14,6 +14,14 @@ export default defineConfig({ assetsDir: 'assets', sourcemap: false, // 生产环境不生成sourcemap minify: 'terser', // 使用terser压缩 + rollupOptions: { + output: { + manualChunks: { + vendor: ['vue', 'vue-router'], + utils: ['axios'] + } + } + } }, // 开发服务器配置(仅开发环境生效) server: { diff --git a/宝塔面板Nginx配置.conf b/宝塔面板Nginx配置.conf new file mode 100644 index 0000000..6e8e9f3 --- /dev/null +++ b/宝塔面板Nginx配置.conf @@ -0,0 +1,83 @@ +# 宝塔面板 Nginx 站点配置 +# 请将以下配置添加到你的站点配置中 + +server { + listen 80; + server_name 2.uzi0.cc; # 你的域名 + index index.php index.html index.htm default.php default.htm default.html; + root /www/wwwroot/2.uzi0.cc; # 修改为你的实际网站根目录路径 + + # SSL配置(如果有SSL证书) + # listen 443 ssl http2; + # ssl_certificate /path/to/your/cert.pem; + # ssl_certificate_key /path/to/your/cert.key; + + # 安全配置 + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Content-Type-Options "nosniff"; + + # 静态资源缓存配置 + location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header Access-Control-Allow-Origin *; + try_files $uri =404; + } + + # API代理配置 - 解决跨域问题 + location /api/ { + proxy_pass http://192.140.164.137:18080/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # CORS头部设置 + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; + add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; + + # 处理OPTIONS预检请求 + if ($request_method = 'OPTIONS') { + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; + add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; + add_header Access-Control-Max-Age 1728000; + add_header Content-Type 'text/plain; charset=utf-8'; + add_header Content-Length 0; + return 204; + } + } + + # Vue SPA 路由配置 - 关键部分! + location / { + try_files $uri $uri/ @fallback; + } + + # SPA回退配置 + location @fallback { + rewrite ^.*$ /index.html last; + } + + # 直接指定index.html处理所有404 + error_page 404 /index.html; + + # 禁止访问的文件类型 + location ~ /\.ht { + deny all; + } + + location ~ /\. { + deny all; + } + + # 宝塔面板默认的安全配置 + location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md) { + return 404; + } + + # 宝塔面板访问日志 + access_log /www/wwwlogs/2.uzi0.cc.log; + error_log /www/wwwlogs/2.uzi0.cc.error.log; +} diff --git a/宝塔面板修改后的配置.conf b/宝塔面板修改后的配置.conf new file mode 100644 index 0000000..58cb1ae --- /dev/null +++ b/宝塔面板修改后的配置.conf @@ -0,0 +1,105 @@ +server +{ + listen 81; + listen 443 ssl http2 ; + listen 991; + listen 80; + server_name 2.uzi0.cc 192.140.164.137; + index index.html index.htm default.htm default.html; + root /www/wwwroot/192.140.164.137_81; + #CERT-APPLY-CHECK--START + # 用于SSL证书申请时的文件验证相关配置 -- 请勿删除并保持这段设置在优先级高的位置 + include /www/server/panel/vhost/nginx/well-known/192.140.164.137_81.conf; + #CERT-APPLY-CHECK--END + + #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则 + #error_page 404/404.html; + ssl_certificate /www/server/panel/vhost/cert/192.140.164.137_81/fullchain.pem; + ssl_certificate_key /www/server/panel/vhost/cert/192.140.164.137_81/privkey.pem; + ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; + ssl_prefer_server_ciphers on; + ssl_session_tickets on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + add_header Strict-Transport-Security "max-age=31536000"; + error_page 497 https://$host$request_uri; + + #SSL-END + + #ERROR-PAGE-START 错误页配置,可以注释、删除或修改 + #error_page 404 /404.html; + #error_page 502 /502.html; + #ERROR-PAGE-END + + #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效 + include /www/server/panel/vhost/rewrite/html_192.140.164.137_81.conf; + #REWRITE-END + + # ========== 新增:API代理配置 - 解决跨域问题 ========== + location /api/ { + proxy_pass http://192.140.164.137:18080/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # CORS头部设置 + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; + add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; + + # 处理OPTIONS预检请求 + if ($request_method = 'OPTIONS') { + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; + add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; + add_header Access-Control-Max-Age 1728000; + add_header Content-Type 'text/plain; charset=utf-8'; + add_header Content-Length 0; + return 204; + } + } + + # ========== 新增:Vue SPA 路由配置 - 关键部分! ========== + location / { + try_files $uri $uri/ @fallback; + } + + # SPA回退配置 + location @fallback { + rewrite ^.*$ /index.html last; + } + + #禁止访问的文件或目录 + location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) + { + return 404; + } + + #一键申请SSL证书验证目录相关设置 + location ~ \.well-known{ + allow all; + } + + #禁止在证书验证目录放入敏感文件 + if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) { + return 403; + } + + location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$ + { + expires 30d; + error_log /dev/null; + access_log /dev/null; + } + + location ~ .*\\.(js|css)?$ + { + expires 12h; + error_log /dev/null; + access_log /dev/null; + } + access_log /www/wwwlogs/192.140.164.137_81.log; + error_log /www/wwwlogs/192.140.164.137_81.error.log; +} diff --git a/宝塔面板操作步骤.md b/宝塔面板操作步骤.md new file mode 100644 index 0000000..ad7c5e0 --- /dev/null +++ b/宝塔面板操作步骤.md @@ -0,0 +1,98 @@ +# 宝塔面板 Vue SPA 部署步骤 + +## 问题解决步骤 + +### 1. 修改 Nginx 配置 + +1. **登录宝塔面板** +2. **进入网站管理** + - 点击 "网站" + - 找到你的站点 `2.uzi0.cc` 或 `192.140.164.137` + - 点击 "设置" + +3. **修改配置文件** + - 点击 "配置文件" 选项卡 + - 在现有配置中添加以下两个关键部分: + +#### 添加 API 代理配置(在 #REWRITE-END 后面添加): +```nginx +# ========== 新增:API代理配置 - 解决跨域问题 ========== +location /api/ { + proxy_pass http://192.140.164.137:18080/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # CORS头部设置 + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; + add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; + + # 处理OPTIONS预检请求 + if ($request_method = 'OPTIONS') { + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; + add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; + add_header Access-Control-Max-Age 1728000; + add_header Content-Type 'text/plain; charset=utf-8'; + add_header Content-Length 0; + return 204; + } +} + +# ========== 新增:Vue SPA 路由配置 - 关键部分! ========== +location / { + try_files $uri $uri/ @fallback; +} + +# SPA回退配置 +location @fallback { + rewrite ^.*$ /index.html last; +} +``` + +### 2. 保存并重载配置 + +1. **保存配置** + - 点击 "保存" 按钮 + +2. **重载 Nginx** + - 宝塔面板会自动重载配置 + - 或者手动点击 "重载配置" + +### 3. 验证部署 + +访问以下链接测试: +- ✅ `http://2.uzi0.cc/` (首页) +- ✅ `http://2.uzi0.cc/play?code=973F2YTE` (游戏页面,之前404的) +- ✅ 刷新游戏页面应该正常 +- ✅ API请求应该不会有CORS错误 + +## 配置说明 + +### API 代理的作用: +- 将前端的 `/api/*` 请求代理到后端服务器 `http://192.140.164.137:18080` +- 解决跨域(CORS)问题 +- 处理预检请求(OPTIONS) + +### SPA 路由配置的作用: +- `try_files $uri $uri/ @fallback;` 首先尝试找实际文件 +- 如果文件不存在,回退到 `@fallback` +- `@fallback` 将所有请求重写到 `index.html` +- 让 Vue Router 处理前端路由 + +## 常见问题 + +### Q: 修改后仍然404 +**A:** 检查配置语法,确保没有语法错误,查看错误日志 + +### Q: API请求失败 +**A:** 检查后端服务 `http://192.140.164.137:18080` 是否正常运行 + +### Q: 静态资源加载失败 +**A:** 检查文件路径,确保 `dist` 目录下的文件都已上传 + +## 完整的修改位置 + +在你的配置文件中,在 `#REWRITE-END` 这一行后面,`#禁止访问的文件或目录` 这一行前面,插入上述的 API 代理和 SPA 路由配置。