You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS 13 App目录下Axios拦截器跳转失效问题求助

NextJS 13中Axios拦截器的跳转问题及解决思路

有人找到在NextJS 13中使用Axios拦截器的解决方案吗?我本以为这应该很简单,但实际并非如此。

客户端组件代码

"use client"
import React, { useState } from 'react'
import axiosInterceptorInstance from '@/lib/request'

interface Device {
    // 设备字段定义
}

export default function DevicesHolder() {
    const [devices, setDevices] = useState<Device[]>([])

    axiosInterceptorInstance.get('/api/v1/staff-admin/devices?page=1&itemsPerPage=20').then((res) => {
        setDevices(res.data.data)
    })

    return (
        <>
            {devices.map((device, key) => (
                <div key={key}>
                    <h1>{device.imei}</h1>
                </div>
            ))}
        </>
    )
}

Axios拦截器代码

import axios from "axios";
import { redirect } from 'next/navigation'

const axiosInterceptorInstance = axios.create({
    baseURL: process.env.NEXT_PUBLIC_API_BASE_URL, // 替换为你的API基础地址
});

axiosInterceptorInstance.interceptors.response.use(
    (response) => {
        // 在这里修改响应数据
        return response;
    },
    (error) => {
        // 处理响应错误
        // 如果未授权,跳转到登录页
        console.log("server", typeof window === 'undefined')
        if (error.response.status === 401) {
            redirect('/login')
        }
  
        return Promise.reject(error);
    }
);
  
export default axiosInterceptorInstance;

问题描述

不知为何,请求会同时在服务端和客户端执行,且两端都无法完成跳转,还抛出了NEXT_REDIRECT错误(这是预期行为吗?)。有没有解决思路?

补充说明:我曾尝试使用window.location.href,但显然在服务端执行时会报错。


解决思路

1. 区分服务端与客户端环境处理跳转

NextJS 13的客户端组件在SSR/SSG阶段会在服务端执行一次,此时调用redirect()会抛出NEXT_REDIRECT错误(这是框架预期行为),而服务端环境下window对象不存在,直接用window.location.href会报错。修改拦截器的错误处理逻辑,分别适配两端:

import axios from "axios";
import { redirect } from 'next/navigation'

const axiosInterceptorInstance = axios.create({
    baseURL: process.env.NEXT_PUBLIC_API_BASE_URL,
});

axiosInterceptorInstance.interceptors.response.use(
    (response) => response,
    (error) => {
        if (error.response?.status === 401) {
            // 客户端环境用window跳转
            if (typeof window !== 'undefined') {
                window.location.href = '/login';
            } else {
                // 服务端环境抛出redirect,让NextJS自动处理服务端跳转
                redirect('/login');
            }
        }
        return Promise.reject(error);
    }
);

export default axiosInterceptorInstance;

2. 避免服务端发起不必要请求

原组件在顶层直接发起请求,会导致SSR阶段服务端也执行一次请求。将请求放到useEffect中,确保仅在客户端执行:

"use client"
import React, { useState, useEffect } from 'react'
import axiosInterceptorInstance from '@/lib/request'
import { isRedirectError } from 'next/dist/client/components/redirect'

interface Device {
    imei: string;
    // 其他字段
}

export default function DevicesHolder() {
    const [devices, setDevices] = useState<Device[]>([])

    useEffect(() => {
        const fetchDevices = async () => {
            try {
                const res = await axiosInterceptorInstance.get('/api/v1/staff-admin/devices?page=1&itemsPerPage=20')
                setDevices(res.data.data)
            } catch (err) {
                // 不要捕获NEXT_REDIRECT错误,让框架处理跳转
                if (!isRedirectError(err)) {
                    // 处理其他业务错误,比如提示用户
                    console.error('获取设备列表失败:', err)
                }
            }
        }
        fetchDevices()
    }, [])

    return (
        <>
            {devices.map((device, key) => (
                <div key={key}>
                    <h1>{device.imei}</h1>
                </div>
            ))}
        </>
    )
}

3. 正确处理服务端跳转的NEXT_REDIRECT错误

服务端调用redirect()抛出的NEXT_REDIRECT错误是NextJS的预期行为,框架会自动捕获并完成跳转,无需手动处理。如果在请求中用try/catch包裹,注意不要捕获该错误,或者判断后重新抛出,避免阻止跳转。

内容的提问来源于stack exchange,提问作者LUKER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:58:25