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

GitLab API通过curl请求正常,NextJS+Axios调用报401错误

GitLab API 401错误:curl成功但NextJS Axios失败的解决方法

问题背景

使用curl调用GitLab API可成功获取项目文件:

curl --header "PRIVATE-TOKEN: <token>" "https://gitlab.companyname.ag/api/v4/projects/projectid/repository/files/<folder>%2f<folder>%2F<folder>%2F<filename>/raw?ref=master"

但在NextJS应用中用Axios调用相同接口却返回401错误,代码如下:

import axios from "axios";
import protobuf from "protobufjs";

async function loadProtoFile() {
  const token = process.env.SERVICES_REPO_ACCESS_TOKEN as string;
  const projectId = "1";
  const branch = "master";
  const filePath = "path/to/file/example.proto";

  const apiUrl = `https://gitlab.<companyname>.ag/api/v4/projects/${projectId}/repository/files/${encodeURIComponent(
    filePath
  )}/raw?ref=${branch}`;

  try {
    const response = await axios.get(apiUrl, {
      headers: {
        "PRIVATE-TOKEN": token,
      },
    });

    return response.data;
  } catch (error: any) {
    console.error(error);
    throw new Error(`Failed to fetch file content: ${error.message}`);
  }
}

已确认请求URL完全一致,但仍出现401错误,寻求解决办法。

可能的原因及解决步骤

1. 环境变量未正确加载(最常见)

NextJS中,客户端组件无法直接访问不带NEXT_PUBLIC_前缀的环境变量,如果loadProtoFile是在客户端组件里调用的,process.env.SERVICES_REPO_ACCESS_TOKEN会返回undefined,导致请求头没有携带有效token。

解决方法:

  • 将请求逻辑移到服务器端(API路由或服务器组件),服务器端可以直接读取所有环境变量。
  • 示例API路由(app/api/proto/route.ts):
import axios from "axios";
import { NextResponse } from "next/server";

export async function GET() {
  const token = process.env.SERVICES_REPO_ACCESS_TOKEN;
  if (!token) {
    return NextResponse.json({ error: "Token未配置" }, { status: 500 });
  }

  const projectId = "1";
  const branch = "master";
  const filePath = "path/to/file/example.proto";
  // 手动转义路径为小写%2f,和curl请求保持一致
  const encodedFilePath = filePath.replace(/\//g, "%2f");
  const apiUrl = `https://gitlab.companyname.ag/api/v4/projects/${projectId}/repository/files/${encodedFilePath}/raw?ref=${branch}`;

  try {
    const response = await axios.get(apiUrl, {
      headers: { "PRIVATE-TOKEN": token },
    });
    return NextResponse.json({ content: response.data });
  } catch (error: any) {
    return NextResponse.json(
      { error: error.message },
      { status: error.response?.status || 500 }
    );
  }
}
  • 客户端通过调用自己的API路由获取数据:
async function loadProtoFile() {
  try {
    const response = await fetch("/api/proto");
    if (!response.ok) throw new Error("请求失败");
    const data = await response.json();
    return data.content;
  } catch (error: any) {
    throw new Error(`获取文件失败: ${error.message}`);
  }
}

2. 路径转义的大小写差异

curl请求中路径用的是小写%2f,但encodeURIComponent会把/转成大写%2F。虽然URL标准不区分大小写,但GitLab API可能对路径编码有严格要求。

解决方法:

  • 替换encodeURIComponent(filePath)为手动转义:
const encodedFilePath = filePath.replace(/\//g, "%2f");

3. 确认请求头是否正确发送

  • 在服务器端代码中添加日志打印token,确认其不为空;
  • 如果是客户端请求,打开浏览器开发者工具的Network面板,查看请求的Request Headers里是否有PRIVATE-TOKEN字段。

4. 验证权限与项目信息

  • 确认projectId与curl中使用的完全一致;
  • 检查token是否拥有该项目的read_repository权限(curl能成功的话通常没问题,但可以在GitLab的个人访问令牌页面确认);
  • 确认分支名称master的拼写与GitLab中完全一致(注意大小写)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:05:29