How can I use Axios to request token settings that are compatible with both the client and server? #86309
SummaryWhen on the server, I am unable to retrieve cookies Additional informationapi.ts
import axios, {AxiosProgressEvent, AxiosRequestConfig, AxiosResponse} from 'axios';
import {deleteCookie, getCookie as getCookieClient} from "cookies-next/client";
import {getCookie as getCookieServer} from "cookies-next/server";
import {addToast} from "@heroui/react";
type ResponseData<T> = {
Code: number;
Msg: string;
Model: T;
}
type DefaultResponseData<T> = T extends void ? ResponseData<any> : ResponseData<T>;
const instance = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_BASE ?? "/Api/v1/Web/",
timeout: 100000,
headers: {
'Content-Type': 'application/json',
},
});
instance.interceptors.request.use(
async (config) => {
const isBrowser = typeof window !== 'undefined';
let token: any
if (isBrowser) {
token = getCookieClient("token")
}
else {
console.log(isBrowser)
token = await getCookieServer("token")
}
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
instance.interceptors.response.use(
async (response) => {
let data = response.data;
const isBrowser = typeof window !== 'undefined';
if(typeof data === 'object' && data[Symbol.toStringTag] === "Blob" && data.type === "application/json"){
const json = await new Response(data).json()
data = json;
response.data=null
}
if (isBrowser && data.Msg) {
if (data.Code === 0) {
addToast({
title: data.Msg,
color: "success",
})
} else {
addToast({
title: data.Msg,
color: "danger"
})
}
}
return response;
},
(error) => {
console.log(error)
if (error && error.status === 401) {
if (typeof window !== 'undefined') {
deleteCookie("token");
window.localStorage.clear()
window.location.href = '/';
return
}
}
else if (error && error.status === 502) {
if (typeof window !== 'undefined') {
addToast({
title: `服务器故障,请稍后重试`,
color: "danger",
})
return
}
}
else{
if (typeof window !== 'undefined') {
addToast({
title: `异常${error.status},${error}`,
color: "danger",
})
return
}
}
console.error('API Error:', error);
return Promise.reject(error);
}
);
export const api = {
/**
* GET request
* @param url - API endpoint
* @param params - Query parameters
* @param config - Additional axios config
*/
get: async <T = void>(
url: string,
params?: Record<string, any>,
config?: AxiosRequestConfig
): Promise<DefaultResponseData<T>> => {
try {
const response: AxiosResponse<T> = await instance.get(url, {
params,
...config,
});
return response.data as DefaultResponseData<T>;
} catch (error) {
throw error;
}
},
/**
* POST request
* @param url - API endpoint
* @param data - Request body
* @param config - Additional axios config
*/
post: async <T = void>(
url: string,
data?: any,
config?: AxiosRequestConfig
): Promise<DefaultResponseData<T>> => {
try {
const response: AxiosResponse<T> = await instance.post(url, data, config);
return response.data as DefaultResponseData<T>;
} catch (error) {
throw error;
}
},
/**
* PUT request
* @param url - API endpoint
* @param data - Request body
* @param config - Additional axios config
*/
put: async <T = any>(
url: string,
data?: any,
config?: AxiosRequestConfig
): Promise<T> => {
try {
const response: AxiosResponse<T> = await instance.put(url, data, config);
return response.data;
} catch (error) {
throw error;
}
},
/**
* Upload file with progress monitoring
* @param url - API endpoint
* @param file - File to upload
* @param onProgress - Progress callback
* @param config - Additional axios config
*/
upload: async <T = any>(
url: string,
file: File,
formData?: Record<string, any>,
onProgress?: (progressEvent: AxiosProgressEvent) => void,
config?: AxiosRequestConfig
): Promise<T> => {
const form = new FormData();
form.append('file', file);
if (formData) {
Object.entries(formData).forEach(([key, value]) => {
form.append(key, value);
});
}
try {
const response: AxiosResponse<T> = await instance.post(url, form, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: onProgress,
responseType: "blob",
...config,
timeout: 600000
});
return response.data as T;
} catch (error) {
throw error;
}
},
};
export default api; |
Answered by
Umuts-Codes
Nov 23, 2025
Replies: 1 comment
|
You can handle Axios requests compatible with both client and server in Next.js by checking the environment and retrieving the token accordingly. Server-side (App Router / server function): import axios from 'axios';
import { cookies } from 'next/headers';
export async function getDataServer() {
const token = cookies().get('token')?.value;
const res = await axios.get('https://api.example.com/data', {
headers: { Authorization: `Bearer ${token}` },
});
return res.data;
}Client-side (Browser): import axios from 'axios';
export async function getDataClient() {
const token = localStorage.getItem('token');
const res = await axios.get('https://api.example.com/data', {
headers: { Authorization: `Bearer ${token}` },
});
return res.data;
}Optional: Shared function for both environments export async function fetchData(isServer = false) {
let token;
if (isServer) {
token = cookies().get('token')?.value;
} else {
token = localStorage.getItem('token');
}
const res = await axios.get('https://api.example.com/data', {
headers: { Authorization: `Bearer ${token}` },
});
return res.data;
}✅ Notes:
|
0 replies
Answer selected by
bbhxwl
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can handle Axios requests compatible with both client and server in Next.js by checking the environment and retrieving the token accordingly.
Server-side (App Router / server function):
Client-side (Browser):