0

我正在尝试将文件和其他一些数据发布到我正在使用 Delphi XE8 编写的应用程序中的网站,但它不起作用。当我使用“Microsoft Network Monitor 3.4”监控网络流量时,文件只发送了一部分,没有发送任何其他数据。我已经尝试过 Indy 10 和新的TNetHTTPClient并得到相同的结果,这告诉我我做错了什么。请帮忙。

印地之路

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;

我知道服务器工作正常,因为另一个应用程序(用 Intel XDA 编写)工作正常。该图像是有效的,并且我在此之前进行的所有Get调用也有效。我真的需要帮助。先感谢您

4

1 回答 1

3

当我使用“Microsoft Network Monitor 3.4”监控网络流量时,文件只发送了一部分,没有发送任何其他数据。

您确定显示器只是没有在其 UI 中显示部分数据吗?像 Wireshark 这样的数据包嗅探器会更可靠(或附加一个TIdLog...组件TIdHTTP),因为它会向您显示实际传输的所有内容。TIdMultipartFormDataStream发布 a只会发送文件的一部分并完全跳过其他字段的唯一可能方法是,如果套接字在传输文件时断开连接。

mimeStr := GetMIMETypeFromFile(fieldValue); // 这将返回 'image/pjpeg' 而不是 'image/jpeg'。

在内部,GetMIMETypeFromFile()构建自己的硬编码 MIME 类型列表,然后使用操作系统信息覆盖该列表。.jpg硬编码的默认值为image/jpeg. 然后,当它查询操作系统时,它看到image/jpegimage/pjpeg(按此顺序)注册了.jpgimage/pjpeg最后看到的 MIME 类型也是如此.jpg,这就是GetMIMETypeFromFile()最终返回的内容。

pHttp.Request.ContentType := PostStream.RequestContentType;

您不需要, Post() 在内部为您处理。

pHttp.Request.AcceptEncoding := 'gzip, deflate';

不要那样做。 Post()根据是否TIdHTTP.Compressor已分配和准备好在内部为您处理。

于 2015-05-15T16:29:29.347 回答