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

OkHttpClient表单请求正常,Ktor实现报错求排查

Ktor Multipart表单请求错误排查与修复

问题背景

使用OkHttpClient发送Multipart表单请求可正常运行,但改用Ktor实现相同逻辑时请求失败。

可正常运行的OkHttpClient代码

val client = OkHttpClient.Builder()
val body = MultipartBody.Builder().setType(MultipartBody.FORM)
    .addFormDataPart("choice", null,
        "John Wick".toRequestBody("application/json".toMediaType()))
    .addFormDataPart("image", path,
        File(path).asRequestBody("application/octet-stream".toMediaType()))
    .build()
val request = Request.Builder()
    .url("https://example.com")
    .post(body)
    .addHeader("Authorization", "Bearer key")
    .build()

无法正常运行的Ktor代码

val httpResponse = client.submitForm {
    url("https://example.com")
    method = HttpMethod.Post
    contentType(ContentType.MultiPart.FormData)
    header("Authorization", "Bearer key")
    body = MultiPartFormDataContent (
        formData {
            append("choice","John Wick", Headers.build {
                append(HttpHeaders.ContentType, ContentType.Application.Json)
            })
            append("image",path,Headers.build {
                append(HttpHeaders.ContentType,  ContentType.Application.OctetStream)
            })
        }
    )
}

问题原因

Ktor代码处理image字段时直接传入了路径字符串,而非文件的二进制内容,同时缺少Content-Disposition头指定文件名,与OkHttpClient的实现逻辑不一致:

  • OkHttpClient会将文件转换为RequestBody发送二进制数据,并自动处理文件名相关请求头
  • Ktor原代码相当于把路径文本作为字段内容发送,并非实际上传文件

修正方案

将Ktor代码中处理image字段的部分替换为:

append("image", File(path).readBytes(), headersOf("Content-Disposition", "filename=$fileName"))

说明:

  • File(path).readBytes()读取文件二进制内容,与OkHttpClient的文件上传行为对齐
  • 添加Content-Disposition头并指定文件名,确保服务端能正确识别文件字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:47:51