将文件作为表单的一部分发布 [英] posting a file as part of a form

查看:83
本文介绍了将文件作为表单的一部分发布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在使用Delphi XE8编写的应用程序中将文件和其他数据发布到网站,但无法正常工作。当我使用 Microsoft Network Monitor 3.4监视网络流量时,该文件仅被部分发送,其他任何数据都没有发送。我已经尝试了Indy 10和新的 TNetHTTPClient ,并得到了相同的结果,告诉我我做错了事。请帮忙。

I am trying to post a file and some other data to a website in an App that I am writing using Delphi XE8 but it is not working. When I monitor the network traffic using "Microsoft Network Monitor 3.4", the file is only partially sent and none of the other data is sent. I have tried both Indy 10 and the new TNetHTTPClient and got the same result which tells me I am doing something wrong. please help.

印地之路

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 返回错误的值,即使我硬编码了正确的方法,没有什么不同。

by the way GetMIMETypeFromFile returns the wrong value but even if I hardcode the correct one, it does not make any different.

新的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 调用也都有效。
我真的需要帮助。
预先感谢

I know the server is working correctly because another application (written in Intel XDA) works just fine. the image is valid, and all the Get calls that I make before this works as well. I really need help. Thank you in advance

推荐答案


当我使用 Microsoft Network监视网络流量时Monitor 3.4,文件仅部分发送,其他数据均不发送。

When I monitor the network traffic using "Microsoft Network Monitor 3.4", the file is only partially sent and none of the other data is sent.

您确定监视器根本没有在其UI中显示部分数据?像Wireshark这样的数据包嗅探器将更可靠(或将 TIdLog ... 组件附加到 TIdHTTP )将向您展示实际传输的所有内容。张贴 TIdMultipartFormDataStream 的唯一可能方法是仅发送文件的一部分,并完全跳过其他字段,如果套接字在传输文件时已断开连接。

Are you sure the monitor is simply not displaying partial data in its UI? A packet sniffer like Wireshark would be more reliable (or attach a TIdLog... component to TIdHTTP), as it will show you everything that is actually being transmitted. The only possible way that posting a TIdMultipartFormDataStream would only send a portion of the file and skip the other fields altogether is if the socket is disconnected while transmitting the file.


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

mimeStr := GetMIMETypeFromFile(fieldValue); // This returns 'image/pjpeg' instead of 'image/jpeg'.

内部, GetMIMETypeFromFile( )构建其自己的硬编码MIME类型列表,然后使用OS信息覆盖该列表。对 .jpg 进行硬编码的默认值为 image / jpeg 。然后,当查询操作系统时,会看到 image / jpeg image / pjpeg (按此顺序)被注册 .jpg ,所以 image / pjpeg .jpg看到的最后一个MIME类型,这就是 GetMIMETypeFromFile()最终返回的结果。

Internally, GetMIMETypeFromFile() builds its own list of hard-coded MIME types and then uses OS information to overwrite that list. The default value that is hard-coded for .jpg is image/jpeg. When it then queries the OS, it sees image/jpeg and image/pjpeg (in that order) are registered for .jpg, so image/pjpeg was the last MIME type seen for .jpg and that is what GetMIMETypeFromFile() ends up returning.


pHttp.Request.ContentType:= PostStream.RequestContentType;

pHttp.Request.ContentType := PostStream.RequestContentType;

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

You do not need that, Post() handles that internally for you.


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

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

完全不要这样做。 Post()根据是否已分配并准备好 TIdHTTP.Compressor 为您内部处理。

Do not do that at all. Post() handles that internally for you, based on whether TIdHTTP.Compressor is assigned and ready.

这篇关于将文件作为表单的一部分发布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆