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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 19:48:03