Next.js中使用自定义API服务调用外部接口时遭遇CORS错误的问题求助
Next.js中使用自定义API服务调用外部接口时遭遇CORS错误的问题求助
我最近在Next.js项目里碰到了一个搞不懂的问题:我写了一个封装Axios的API服务文件,本来是想让接口调用更规范、更高效,但通过这个服务调用后端接口时就会触发CORS错误,可直接在组件里用Axios原生方法调用却完全正常,这实在太奇怪了!
我的自定义API服务代码(apiService.ts)
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; const apiClient = axios.create({ baseURL: 'http://localhost:4000', headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', // 尝试添加这个头解决CORS,但没用 }, withCredentials: true, }); // 通用GET请求封装 export const get = async <T>(url: string, config?: AxiosRequestConfig): Promise<T> => { try { const response: AxiosResponse<T> = await apiClient.get(url, config); return response.data; } catch (error) { console.error('GET request error:', error); throw error; } }; // 通用POST请求封装 export const post = async <T, R>(url: string, data: T, config?: AxiosRequestConfig): Promise<R> => { try { const response: AxiosResponse<R> = await apiClient.post(url, data, config); return response.data; } catch (error) { console.error('POST request error:', error); throw error; } }; // 通用PUT请求封装 export const put = async <T, R>(url: string, data: T, config?: AxiosRequestConfig): Promise<R> => { try { const response: AxiosResponse<R> = await apiClient.put(url, data, config); return response.data; } catch (error) { console.error('PUT request error:', error); throw error; } }; // 通用DELETE请求封装 export const deleteRequest = async <T>(url: string, config?: AxiosRequestConfig): Promise<T> => { try { const response: AxiosResponse<T> = await apiClient.delete(url, config); return response.data; } catch (error) { console.error('DELETE request error:', error); throw error; } };
组件中的调用代码(ModalCreateExercise.tsx)
'use client' import { zodResolver } from "@hookform/resolvers/zod" import { SubmitHandler, useForm } from "react-hook-form" import { z } from "zod" import axios from 'axios'; import { BaseModal } from "@/components/commun/BaseModal" import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form" import { Input } from "@/components/ui/input" import { Button } from "@/components/ui/button" import { createExercise, getExercises } from "@/services/exerciseService" import { Exercise } from "@/types/exercise" import { useEffect, useState } from "react" import { get, post } from "@/app/services/axiosService"; const formSchema = z.object({ name: z.string().min(2, { message: "Username must be at least 2 characters.", }), }) export function ModalCreateExercise() { const [exercises, setExercises] = useState<Exercise[]>([]); // ✅ 这个是正常工作的:直接用Axios原生方法调用 useEffect(() => { const fetchExercises = async () => { try { const response = await axios.get<Exercise[]>('http://localhost:4000/exercises'); console.log('Exercises fetched:', response.data); } catch (error) { console.error('Error fetching exercises:', error); } }; fetchExercises(); }, []); // ❌ 这个不工作:用自定义服务的get方法调用,触发CORS错误 useEffect(() => { const fetchExercises = async () => { try { const response = await get<Exercise[]>('/exercises'); console.log('Exercises fetched:', response); } catch (error) { console.error('Error fetching exercises:', error); } }; fetchExercises(); }, []); const form = useForm<z.infer<typeof formSchema>>({ resolver: zodResolver(formSchema), defaultValues: { name: "" }, }) const onSubmit = async() => { const data: Exercise = { userId: 1, name: form.getValues().name, }; // ❌ 同样,用自定义服务的post方法也会触发CORS错误 try { const newExercise = await post<typeof data, Exercise>('/exercises', data); console.log('Exercise created:', newExercise); } catch (error) { console.error('Error creating exercise:', error); } }; return ( <BaseModal className="ml-auto" title="Créer un exercice" description="Créer un exercice pour vos étudiants" buttonTitle="Créer un exercice" saveButtonTitle="Créer"> <div> <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8"> <FormField control={form.control} name="name" render={({ field }) => ( <FormItem> <FormLabel>Nom de l'exercice</FormLabel> <FormControl> <Input placeholder="Nom" {...field} /> </FormControl> <FormMessage /> </FormItem> )} /> <Button type="submit">Submit</Button> </form> </Form> </div> </BaseModal> ) }
问题核心与我的尝试
具体来说:
- 直接在组件中用Axios原生方法请求
http://localhost:4000/exercises,完全正常,没有任何CORS问题 - 换成自定义服务的
get<Exercise[]>('/exercises')调用,就会触发CORS报错 - 后端是NestJS写的,已经配置了CORS允许跨域请求,而且只有通过自定义服务调用时才会出问题,感觉后端好像不认这个服务发的请求似的
我已经做了这些尝试,但都没解决问题:
- 反复检查了NestJS后端的CORS配置,确认是正确的
- 在自定义Axios实例里手动添加了
Access-Control-Allow-Origin: *请求头,但完全没用
我怀疑是不是Axios的配置或者Cookie处理哪里有问题?有没有大佬能帮我分析下原因呀?谢谢啦!
备注:内容来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

