背景
最近在做一个关于短信留言的项目, 防止自己突发意外 来不及向亲友告别, 而留下遗憾.
使用不同的前端框架方案分别进行了实现. 可点击前往体验
其中遇到了 Vite + history模式下 打包部署到服务器子目录后, 跨域请求的问题.
因需要注意的点较多, 所以记录一下, 也希望后来人可以少踩坑. 😄
PS: 本文讲述的是部署到生产环境子目录遇到的问题, 为了方便讲述, 做如下假设和约定:
1. 在本地调用API接口是正常的.
2. 部署子目录为:"demo", http://xx.com 可正常访问, 期望通过 http://xx.com/demo 进行访问
3. API接口地址为 http://api.com/v1/user (/user是不同的接口路径, 前面是固定的)
正文
我们的期望: vite项目在本地开发调试完成后, 打包到dist文件夹, 然后上传到你的服务器子目录(demo)中; 就可以通过 http://xx.com/demo 进行访问了.
可能遇到的问题:
①、上传到demo目录后, 访问页面报错或空白, 打开控制台发现报各种404错误.
原因: 打包时没有设置子目录, 默认按照根目录进行打包的, 这样的话, 页面引用的各种文件路径就不对了.
解决办法: 可修改路由模式为 mode: 'hash', 但这样地址栏会一直有#, 不美观.
我们使用如下解决办法:
1. vite配置文件 vite.config.js
export default defineConfig({ base: '/demo', // 部署时的子目录 ... })
2. 路由配置文件 router/index.js
const router = createRouter({ history: createWebHistory('/demo'), // 部署时的子目录 routes: ... })
3. 重新build打包上传.
②、点击跳转都正常, 但是刷新页面就报404了
原因: 还是路由history模式的问题,
解决办法: 修改Nginx配置文件
location /demo { # 限制在具体目录
try_files $uri $uri/ /demo/index.html; # 防止刷新后404
}
③、请求API接口报错
405 Method Not Allowed: 静态文件不允许非GET请求
解决办法: nginx配置文件增加: error_page 405 = 200 $request_uri;
报404 / 500: 大概率是接口路径或nginx配置导致的
需要的文件配置汇总: ↓↓↓请留意下面文件的注释说明↓↓↓
vite.config.js
import { defineConfig } from 'vite' ... export default defineConfig({ base: '/demo', // 部署时的子目录 server: { proxy: { // 此处配置只能解决本地的跨域问题, 不会被打包到生产环境, // // 所以需要在前端项目所在的站点 为nginx配置反向代理, 不是提供api接口所在的站点哦! // '/apiUrl': { target: 'http://api.com/', changeOrigin: true, //支持跨域 rewrite: path => path.replace(/^\/apiUrl/, '') }, } }, ... })
路由文件 router/index.js
import { createRouter, createWebHistory } from 'vue-router' export const constRoutes = [ { path: '/login', component: () => import('../views/login/index.vue') } ] const router = createRouter({ history: createWebHistory('/demo'), // 部署时的子目录 routes: constRoutes })
接口请求文件 user.js
// 也可对axios封装, 把接口前缀apiUrl 放在baseURL中. import axios from '@/utils/axios' export function editUser(data) { return axios.post('/apiUrl/v1/user', data); // 注意此处的apiUrl, 和vite.config.js以及nginx配置都是有对应关系的. }
Nginx配置文件:
location /demo { # 限制具体目录 try_files $uri $uri/ /demo/index.html; # 防止刷新后404 error_page 405 =200 $request_uri; # 解决静态文件无法处理get之外的请求 } location /apiUrl/ { # 反向代理 proxy_pass http://api.com/; # api接口地址 匹配/apiUrl/ -> 然后替换 }
好了, 相关的文件如何配置 都列出来了. 如有任何问题, 欢迎评论区讨论~