将文件作为表单的一部分发布
posting a file as part of a form
我正在尝试 post 一个文件和一些其他数据到我正在使用 Delphi XE8 编写的应用程序中的网站,但它不起作用。当我使用 "Microsoft Network Monitor 3.4" 监视网络流量时,仅发送了部分文件,发送了其他数据的 none。我已经尝试了 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 returns 错误的值,但即使我硬编码正确的值,也没有任何不同。
新的 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 调用也有效。
我真的需要帮助。
提前谢谢你
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
只会发送文件的一部分并完全跳过其他字段的唯一可能方法是,如果套接字在传输文件时断开连接。
mimeStr := GetMIMETypeFromFile(fieldValue); // This returns 'image/pjpeg' instead of 'image/jpeg'.
在内部,GetMIMETypeFromFile()
构建自己的硬编码 MIME 类型列表,然后使用 OS 信息覆盖该列表。 .jpg
的硬编码默认值为 image/jpeg
。当它随后查询 OS 时,它会看到 image/jpeg
和 image/pjpeg
(按该顺序)注册了 .jpg
,因此 image/pjpeg
是最后看到的 MIME 类型对于 .jpg
,这就是 GetMIMETypeFromFile()
最终返回的内容。
pHttp.Request.ContentType := PostStream.RequestContentType;
你不需要那个,Post() 会在内部为你处理。
pHttp.Request.AcceptEncoding := 'gzip, deflate';
根本不要那样做。 Post()
根据 TIdHTTP.Compressor
是否已分配并准备就绪,在内部为您处理。
我正在尝试 post 一个文件和一些其他数据到我正在使用 Delphi XE8 编写的应用程序中的网站,但它不起作用。当我使用 "Microsoft Network Monitor 3.4" 监视网络流量时,仅发送了部分文件,发送了其他数据的 none。我已经尝试了 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 returns 错误的值,但即使我硬编码正确的值,也没有任何不同。
新的 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 调用也有效。 我真的需要帮助。 提前谢谢你
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
只会发送文件的一部分并完全跳过其他字段的唯一可能方法是,如果套接字在传输文件时断开连接。
mimeStr := GetMIMETypeFromFile(fieldValue); // This returns 'image/pjpeg' instead of 'image/jpeg'.
在内部,GetMIMETypeFromFile()
构建自己的硬编码 MIME 类型列表,然后使用 OS 信息覆盖该列表。 .jpg
的硬编码默认值为 image/jpeg
。当它随后查询 OS 时,它会看到 image/jpeg
和 image/pjpeg
(按该顺序)注册了 .jpg
,因此 image/pjpeg
是最后看到的 MIME 类型对于 .jpg
,这就是 GetMIMETypeFromFile()
最终返回的内容。
pHttp.Request.ContentType := PostStream.RequestContentType;
你不需要那个,Post() 会在内部为你处理。
pHttp.Request.AcceptEncoding := 'gzip, deflate';
根本不要那样做。 Post()
根据 TIdHTTP.Compressor
是否已分配并准备就绪,在内部为您处理。