Post 通过 ktor-client 多部分

Post multipart via ktor-client

我必须通过 ktor-client 发出多部分请求。请求方式:

    suspend fun uploadPhoto(userId: String, bitmapPhoto: BitmapPhoto) {
        kotlin.runCatching {
            val response: HttpResponse = httpClient.submitFormWithBinaryData(
                url = BASE_URL.plus("$userId/${bitmapPhoto.name}"),
                formData = formData {
                    append("file", bitmapPhoto.bitmap.toByteArray(),
                        Headers.build {
                            append(HttpHeaders.ContentType, "multipart/form-data; boundary=boundary")
                            append(HttpHeaders.ContentDisposition, "form-data; name=file; filename=${bitmapPhoto.name}")
                        }
                    )
                }
            )
}

执行请求时服务器returns出错。 有正确请求的例子

POST https://host-name.com
Content-Type: multipart/form-data; boundary=boundary;

--boundary
Content-Disposition: form-data; name="file"; filename="image.png"

< C:/path/image.png
--boundary

所以我不明白我的 kotlin 方法哪里不正确

更新 方法的第一个变体是

    suspend fun uploadPhoto(userId: String, bitmapPhoto: BitmapPhoto) {
        kotlin.runCatching {
            val response: HttpResponse = httpClient.submitFormWithBinaryData(
                url = BASE_URL.plus("$userId/${bitmapPhoto.name}"),
                formData = formData {
                    append("file", bitmapPhoto.bitmap.toByteArray(),
                        Headers.build {
                            append(HttpHeaders.ContentType, "image/png")
                            append(HttpHeaders.ContentDisposition, "filename=${bitmapPhoto.name}")
                        }
                    )
                }
            )
}

但是没用所以

问题在以下headers:

append(HttpHeaders.ContentType, "multipart/form-data; boundary=boundary")
append(HttpHeaders.ContentDisposition, "form-data; name=file; filename=${bitmapPhoto.name}")

Content-Type header 应该有你的文件内容的 MIME 类型 (bitmapPhoto),而不是请求的类型 body (Ktor 添加它自动),例如image/pngContent-Disposition header 对于你的情况应该只有 filename=${bitmapPhoto.name} 值,因为 Ktor 会自动添加 form-data; name=file;。所以你的代码应该是这样的:

append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=${bitmapPhoto.name}")

更多信息,请参考Ktor documentation