我正在尝试将文件和其他一些数据发布到我正在使用Delphi XE8编写的应用程序中的网站,但它无法正常工作。当我使用“Microsoft Network Monitor 3.4”监控网络流量时,该文件仅部分发送,并且不发送任何其他数据。我已经尝试了Indy 10和新的 TNetHTTPClient 并得到了相同的结果,它告诉我我做错了什么。请帮忙。
Indy Way
procedure TMyClass.SendFile(aUrl: String);
var
mCookies: TIdCookieManager;
pHttp: TIdHTTP;
PostStream: TIdMultiPartFormDataStream;
ResponseStream: TStringStream;
fName, mimeStr: String;
begin
fName := 'Image000.jpg';
mCookies := TIdCookieManager.Create(nil);
pHttp := TIdHTTP.Create(nil);
pHttp.CookieManager := mCookies;
PostStream:= TIdMultiPartFormDataStream.Create();
ResponseStream := TStringStream.Create('');
mimeStr := GetMIMETypeFromFile(fieldValue); // This returns 'image/pjpeg' instead of 'image/jpeg'. I have manually fixed it and it did not change the result
PostStream.AddFile('sourceFile', fName, mimeStr);
PostStream.AddFormField('name1', 'value1');
PostStream.AddFormField('name2', 'value2');
PostStream.AddFormField('name3', 'value3');
PostStream.AddFormField('name4', 'value4');
PostStream.AddFormField('name5', 'value5');
.
.
.
pHttp.Request.ContentType := PostStream.RequestContentType;
pHttp.Request.Accept := '*/*';
pHttp.Request.AcceptLanguage := 'en-us,en';
pHttp.Request.AcceptEncoding := 'gzip, deflate';
pHttp.Post(aUrl, PostStream, ResponseStream); // Get a 500 error from server for bad data
.
.
.
PostStream.Free();
ResponseStream.Free();
mCookies.Free();
pHttp.Free();
end;
顺便说一下, GetMIMETypeFromFile 会返回错误的值,但即使我对正确的值进行硬编码,也不会有任何不同。
新的XE8方式
procedure TMyClass.SendFile(aUrl: String);
var
mCookies: TCookieManager;
pHttp: TNetHTTPClient;
fName: String;
mpFormData: TMultipartFormData;
respData: IHTTPResponse;
begin
fName := 'Image000.jpg';
mCookies := TCookieManager.Create();
pHttp := TNetHTTPClient.Create(nil);
pHttp.CookieManager := mCookies;
mpFormData := TMultipartFormData.Create();
mpFormData.AddFile('sourceFile', fName);
mpFormData.AddField('name1', 'value1');
mpFormData.AddField('name2', 'value2');
mpFormData.AddField('name3', 'value3');
mpFormData.AddField('name4', 'value4');
mpFormData.AddField('name5', 'value5');
.
.
.
pHttp.ContentType := 'multipart/form-data';
pHttp.Accept := '*/*';
pHttp.AcceptLanguage := 'en-us,en';
pHttp.AcceptEncoding := 'gzip, deflate';
mpFormData.Stream.Position := 0;
respData := pHttp.Post(aUrl, mpFormData.Stream); //Same problem, error 500 here
.
.
.
mpFormData.Free();
pHttp.Free();
mCookies.Free();
end;
我知道服务器工作正常,因为另一个应用程序(用英特尔XDA编写)可以正常工作。图像有效,并且在此之前我所做的所有获取调用也都有效。 我真的需要帮助。 提前谢谢
答案 0 :(得分:2)
当我使用“Microsoft Network Monitor 3.4”监控网络流量时,该文件仅部分发送,并且不会发送任何其他数据。
您确定显示器根本没有在其UI中显示部分数据吗?像Wireshark这样的数据包嗅探器会更可靠(或将TIdLog...
组件附加到TIdHTTP
),因为它会向您显示实际传输的所有内容。发布TIdMultipartFormDataStream
的唯一可能方式是只发送文件的一部分并完全跳过其他字段,如果套接字在传输文件时断开连接。
mimeStr:= GetMIMETypeFromFile(fieldValue); //这将返回'image / pjpeg'而不是'image / jpeg'。
在内部,GetMIMETypeFromFile()
构建自己的硬编码MIME类型列表,然后使用操作系统信息覆盖该列表。 .jpg
硬编码的默认值为image/jpeg
。然后,当它查询操作系统时,会看到image/jpeg
和image/pjpeg
(按此顺序)注册.jpg
,因此image/pjpeg
是{{1}所见的最后一种MIME类型这就是.jpg
最终返回的内容。
pHttp.Request.ContentType:= PostStream.RequestContentType;
你不需要那个,Post()在内部为你处理。
pHttp.Request.AcceptEncoding:='gzip,deflate';
根本不要这样做。 GetMIMETypeFromFile()
根据Post()
是否已分配并准备就绪,为您内部处理。