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
相关产品推荐
相关产品推荐

