HttpClient POST 上传失败,没有文件传输和格式错误的生成内容处置
Posted
技术标签:
【中文标题】HttpClient POST 上传失败,没有文件传输和格式错误的生成内容处置【英文标题】:HttpClient POST upload fails with no file transfered and maleformed generated ContentDisposition 【发布时间】:2019-12-25 21:23:25 【问题描述】:我尝试在我自己的图像主机上镜像图像,它包含一个接受默认表单数据上传的简单 API,如下所示:
-----------------------------149841124823007
Content-Disposition: form-data; name="file"; filename="ZMVdEwM.png"
Content-Type: image/png
<Binary image data...>
此上传使用简单的 html 表单进行了测试,效果很好。现在我想在 .NET Core Standard 应用程序中使用这个 API。找到differentexamples:
string url = "https://i.imgur.com/0acC9nr.png";
var client = new HttpClient();
var imageData = client.GetByteArrayAsync(url).Result;
var content = new MultipartFormDataContent($"-----------------------------DateTime.Now.Ticks");
content.Headers.ContentType = MediaTypeHeaderValue.Parse("image/png");
string fileName = new Uri(url).LocalPath.Replace("/", "");
content.Add(new ByteArrayContent(imageData), "file", fileName);
var postResp = client.PostAsync("https://my-image-hoster/api.php", content).Result;
string resp = postResp.Content.ReadAsStringAsync().Result;
Console.WriteLine(resp);
我正在下载测试图像https://i.imgur.com/0acC9nr.png 作为字节数组并尝试构建相同的表单数据上传。但它在我的 api 上失败了:
if (!isset($_FILES['file']))
echo json_encode(array('errorcode' => 'no_image_transfered'));
在调查问题时,我检查了名为 content
的 MultipartFormDataContent
实例,因为它负责构建请求正文。它显示了一个包含文件名的ContentDisposition
属性两次:第一个是正确的,但第二个看起来是畸形的:
我的 POST 请求有什么问题?
【问题讨论】:
【参考方案1】:发现MultipartFormDataContent.Headers.ContentType
是HTTP头的值:
Content-Type: multipart/form-data; boundary=--------------149841124823007
这取自example,它破坏了我的API,因为它需要multipart/form-data
。因此最好关闭该类型,除非您的 API 检查 $_FILES['file'][0]['type']
中提供的文件类型,因为这是空的。类型来自正文:
Content-Disposition: form-data; name="file"; filename="ZMVdEwM.png"
Content-Type: image/png <--- type
由于它是客户端提供的值,我们shouldn't trust this data 并在服务器端获取mime-type。如果你有一个检查这个值的 API(并且对 API 本身没有影响),只需像这样为 body 设置它:
content.ElementAt(0).Headers.ContentType = MediaTypeHeaderValue.Parse("image/png");
否则,如果您可以上传不包含 mime 类型的 multipart/form-data
,请按以下方式进行上传:
string url = "https://i.imgur.com/0acC9nr.png";
var client = new HttpClient();
var imageData = client.GetByteArrayAsync(url).Result;
var content = new MultipartFormDataContent();
string fileName = new Uri(url).LocalPath.Replace("/", "");
content.Add(new ByteArrayContent(imageData), "file", fileName);
// Optionally when the Content-Type body field is required
// content.ElementAt(0).Headers.ContentType = MediaTypeHeaderValue.Parse("image/png");
var postResp = client.PostAsync("https://my-image-hoster/api.php", content).Result;
var resp = postResp.Content.ReadAsStringAsync().Result;
【讨论】:
以上是关于HttpClient POST 上传失败,没有文件传输和格式错误的生成内容处置的主要内容,如果未能解决你的问题,请参考以下文章
java使用httpclient通过post方式提交表单失败求助