nextjs同一个域名下配置子路由

1,055 阅读2分钟

背景:

有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…