背景:
有2个前端,一个店员端,一个客户端,都是用nextjs,部署到线上环境的时候要配置域名,都会以example.com 开头, 客户端是example.com ,店员端是example.com/admin
结论:
在next.config中配置
const nextConfig = {
basePath: '/admin'
}
然后axios的baseURL改成
baseURL: "<https://xample.com/api/>",
debug过程:
一开始axios是baseURL :”/” 然后next.config配置 rewrites
async rewrites() {
return [
{
source: '/:path*',
destination: `${process.env.HOST}/:path*`,
}
]
},
然后需求下来了 说要配置子路由,我就新增了basePath
basePath: '/admin',
这样一加 访问所有页面都要加上/admin前缀 是可以 但是又遇到一个问题:在首页会检测有没有token,如果没有会跳转到login页面,可是在跳转的时候发现会跳转成/login 按道理来讲应该跳到/admin/login 我怀疑是我跳转的逻辑写错了
const handleNav = (dest: string) => {
const basePath = '/admin';
const router = useRouter();
// Ensure that `dest` does not already include the `basePath`
if (!dest.startsWith(basePath)) {
dest = `${basePath}${dest}`;
}
router.push(dest);
};
没用,一番排查,发现axios的拦截器里对响应做了拦截,拦截之后判断token(如下),而我的首页里面用了useSWR会自动请求一个接口 即使用户什么也没有操作也会请求
http.interceptors.response.use(
response => {
//Forbidden request
if (response?.data?.msg === 'Forbidden request') {
//跳到登录页
removeToken()
window.location.replace('/login')//这里不受next的basePath控制 裂开
}
return Promise.resolve(response);
},
(error) => {
return Promise.reject(error)
}
)
这部分代码不是我写的 然后我没有看别人写的代码
so,改成window.location.replace('/admin/login') 就可以了跳转了
跳转的问题解决后 还有请求接口的问题,上面加了basePath,会导致所有请求也都加了basePath前缀 所以在rewrites里面配置basePath:false
const nextConfig = {
basePath: '/admin',
async rewrites() {
return [
{
source: '/:path*',///
destination: `${process.env.HOST}/:path*`,
basePath:false
}
]
},
但是这样子请求会报500,一看请求url是http://localhost:3000/login 说明rewrites没有生效 如果生效 请求应该是example.com/api/login(e…) 为什么不生效呢
尝试在next.config中判断环境 使用assetPrefix配置静态资源,而不用basePath 这样子去调login这个接口 返回的是html 尝试重新写login的接口,/api/login 再用rewrites匹配到/login 就调env里面的 不行 rewrite没有生效,尝试直接改axios里面baseurl 还是遇到一样的跨域问题
尝试了env是
HOST='<https://example.com/api/>'
axios是 baseURL: "/",
在本地可以跑 在线上发现请求没有加上api 这是为什么
另外换了env 因为终端报错说/example.com这个不在dns列表里面 说明证书没有配好 本地还是可以跑 再试一下线上 大概率是不行 我猜测 之所以没有api 是因为 在本地跑的时候 请求的url是
http://localhost:3000/orderhistory?page=1&phone=&reference=&state=&begin_date=&end_date=,而部署到线上,host就是服务器 所以直接就是example.com/xxx就没有api
本地跑的时候,虽然浏览器network里看到的请求url是http://localhost:3000 开头, 但是最终next会转发到env里面配置的服务器
因为rewrites的作用是对请求url重写 所以我直接改变axios的baseURL为example.com/api/,不用rewr…