在对接 Dify 文件上传接口时,遇到了一个比较隐蔽的问题:
使用 Postman 请求接口完全正常,但在 Java 代码中调用却一直返回 403 Forbidden

最终排查发现问题并不在代码逻辑,而是在 HTTP 请求头的 User-Agent 上。本文记录完整排查过程和最终解决方案,供后续遇到类似问题的人参考。


一、问题现象

调用 Dify 文件上传接口:

POST https://api.dify.ai/v1/files/upload

Java 日志如下:

2026-03-11 16:05:19.968  INFO  上传文件到dify接口
url: https://api.dify.ai/v1/files/upload
参数: {file=[Byte array resource], user=[xxx]}

2026-03-11 16:05:21.316 ERROR 上传文件到 Dify 时发生异常
org.springframework.web.client.HttpClientErrorException: 403 Forbidden

接口返回:

403 Forbidden

使用 Postman 调用同一接口、同一 API Key、同一文件时可以成功上传


二、初步排查方向

因为 Postman 可以成功,而代码失败,基本可以确定:

问题不在接口本身,而在 HTTP 请求差异

主要从以下几个方向排查:

排查项结果
API Key正确
接口地址正确
文件参数正确
multipart/form-data正确
文件名 filename已设置
文件大小正常

Java 代码如下:

public FileUploadResponse uploadFile(MultipartFile multipartFile, String userId, String difyApiKey) throws IOException {
    String uploadUrl = difyUrl + "/files/upload";

    MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();

    ByteArrayResource fileResource = new ByteArrayResource(multipartFile.getBytes()) {
        @Override
        public String getFilename() {
            return multipartFile.getOriginalFilename();
        }
    };

    body.add("file", fileResource);
    body.add("user", userId);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    headers.set("Authorization", "Bearer " + difyApiKey);

    HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);

    ResponseEntity<FileUploadResponse> response = restTemplate.exchange(
            uploadUrl,
            HttpMethod.POST,
            entity,
            FileUploadResponse.class
    );

    return response.getBody();
}

从代码上看完全符合接口要求。


三、关键突破:对比 Postman 请求

在 Postman 中导出 curl 请求:

curl --location 'https://api.dify.ai/v1/files/upload' \
--header 'Authorization: Bearer app-xxxx' \
--form 'file=@"/Users/test/a.pdf"' \
--form 'user="test-user"'

然后对比 Java 请求和 Postman 请求的 Header

发现一个关键差异:

Postman

User-Agent: PostmanRuntime/7.36.0

Java RestTemplate 默认

User-Agent: Java/1.8.0_xxx

四、问题原因

Dify Cloud 的 API 网关(通常是 Cloudflare / WAF)
会对某些 自动化客户端 User-Agent 进行风控。

默认 Java 客户端:

Java/1.8
Apache-HttpClient

可能被识别为:

  • 爬虫
  • 自动脚本
  • 可疑请求

因此网关直接返回:

403 Forbidden

而 Postman 的 User-Agent 被认为是正常客户端,因此请求可以通过。


五、解决方案

在请求头中显式添加 User-Agent

headers.set("User-Agent", "monitor-platform/1.0");

例如:

HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(difyApiKey);
headers.set("User-Agent", "monitor-platform/1.0");
headers.setContentType(MediaType.MULTIPART_FORM_DATA);

这样既可以通过网关,也更符合 API 使用规范。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐