使用 PUT 通过 TIdHTTP 上传文件
Use PUT to upload file with TIdHTTP
我想在 TIdHttp 上使用 PUT 上传文件。我从 Remy Lebeau 那里找到了一个答案,说不要使用 PUT,而是使用 POST。
但是,在我的情况下我不能这样做,因为我正在使用第三个 API,它指定我需要使用 PUT。如果我尝试使用 POST,它会 return 给我一条消息,指出该方法不被允许。
基本上,我正在尝试做这样的事情:
Response := TStringStream.Create;
DS := TIdMultiPartFormDataStream.Create;
DS.AddFile('fileUpload2', 'C:\Users\r.rezino\Desktop\teste.po', 'application/octet-stream');
FHttpComunication.Request.ContentType := 'multipart/form-data';
FHttpComunication.Put(UrlCmd, DS, Response);
但是当我这样做时,我得到一个 500 - Internal server error
。
如果我删除:
FHttpComunication.Request.ContentType := 'multipart/form-data';
我得到 400 - Bad Request
.
我已经尝试直接从浏览器(高级 REST 客户端 - chrome)发出请求并且它有效。所以 API 正在工作。工作时的消息头是:
PUT /api/2/project/XXXXXXXX/resource/export1po/translation/en/ HTTP/1.1
HOST: www.XXXXXXXXXXXXX.com
authorization: Basic XXXXXXXXXXXXX
content-type: multipart/form-data; boundary=----WebKitFormBoundaryPWT8bUdkQ1ZVLHdL
accept: application/json
accept-encoding: gzip, deflate
accept-language: en-US,en;q=0.8
user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
content-length: 1936
------WebKitFormBoundaryPWT8bUdkQ1ZVLHdL
Content-Disposition: form-data; name="fileUpload2"; filename="teste.po"
Content-Type: application/octet-stream
代码不在这里,但是是的,我配置了授权信息,它工作正常,我可以检查这个,因为我可以使用其他人调用 API。
更新
这是我正在尝试使用的 API PUT
:http://docs.transifex.com/api/translations/#put
我尝试过的方法:
1) 这个return500 - Internal Server Error
。我也尝试过创建内容类型为 application/octet-stream
的 DS 对象。但是我得到了同样的错误。
Response := TStringStream.Create;
DS := TIdMultiPartFormDataStream.Create;
DS.AddFile('fileUpload2', 'C:\Users\r.rezino\Desktop\teste.po', 'multipart/form-data');
try
FHttpComunication.Request.ContentType := 'multipart/form-data';
FHttpComunication.Put(UrlCmd, DS, Response);
Result := Response.DataString;
finally
Response.Free;
DS.Free;
end;
2) 答案中建议的方式,但它不起作用。我也收到错误 500
。
PutData := TFileStream.Create('C:\Users\r.rezino\Desktop\teste.po', fmOpenRead or fmShareDenyWrite);
Response := TStringStream.Create;
try
FHttpComunication.Request.ContentType := 'multipart/form-data'; //I tried with and without it
FHttpComunication.Put(UrlCmd, PutData, Response);
Result := Response.DataString;
finally
Response.Free;
PutData.Free;
end;
API 被设计破坏了。你不应该混用 multipart/form-data
和 PUT
。你应该这样发送
FPutData:=TFileStream.Create('yourfile.dat', fmOpenRead or fmShareDenyWrite);
FHTTP.Put('http://...', FPutData, FResponseStream);
但如果不行,问题可能是你没有设置正确的ContentType
,它不包括边界。像这样修复它
FHTTP.Request.ContentType:=DS.RequestContentType;
其中 DS
是您的 TIdMultiPartFormDataStream
。
我发现了问题。这是关于我必须设定的界限。所以最后的结果是:
DS := TIdMultiPartFormDataStream.Create;
DS.AddFile('fileUpload2', 'C:\Users\r.rezino\Desktop\teste.po', 'application/octet-stream');
try
FHttpComunication.Request.ContentType := 'multipart/form-data; boundary=' + DS.Boundary;
FHttpComunication.Request.AcceptEncoding := '';
FHttpComunication.Request.Accept := '';
FHttpComunication.Request.Host := '';
FHttpComunication.Request.UserAgent := '';
FHttpComunication.Put(UrlCmd, DS, Response);
finally
DS.Free;
Response.Free;
end;
我想在 TIdHttp 上使用 PUT 上传文件。我从 Remy Lebeau 那里找到了一个答案,说不要使用 PUT,而是使用 POST。
但是,在我的情况下我不能这样做,因为我正在使用第三个 API,它指定我需要使用 PUT。如果我尝试使用 POST,它会 return 给我一条消息,指出该方法不被允许。
基本上,我正在尝试做这样的事情:
Response := TStringStream.Create;
DS := TIdMultiPartFormDataStream.Create;
DS.AddFile('fileUpload2', 'C:\Users\r.rezino\Desktop\teste.po', 'application/octet-stream');
FHttpComunication.Request.ContentType := 'multipart/form-data';
FHttpComunication.Put(UrlCmd, DS, Response);
但是当我这样做时,我得到一个 500 - Internal server error
。
如果我删除:
FHttpComunication.Request.ContentType := 'multipart/form-data';
我得到 400 - Bad Request
.
我已经尝试直接从浏览器(高级 REST 客户端 - chrome)发出请求并且它有效。所以 API 正在工作。工作时的消息头是:
PUT /api/2/project/XXXXXXXX/resource/export1po/translation/en/ HTTP/1.1 HOST: www.XXXXXXXXXXXXX.com authorization: Basic XXXXXXXXXXXXX content-type: multipart/form-data; boundary=----WebKitFormBoundaryPWT8bUdkQ1ZVLHdL accept: application/json accept-encoding: gzip, deflate accept-language: en-US,en;q=0.8 user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36 content-length: 1936 ------WebKitFormBoundaryPWT8bUdkQ1ZVLHdL Content-Disposition: form-data; name="fileUpload2"; filename="teste.po" Content-Type: application/octet-stream
代码不在这里,但是是的,我配置了授权信息,它工作正常,我可以检查这个,因为我可以使用其他人调用 API。
更新
这是我正在尝试使用的 API PUT
:http://docs.transifex.com/api/translations/#put
我尝试过的方法:
1) 这个return500 - Internal Server Error
。我也尝试过创建内容类型为 application/octet-stream
的 DS 对象。但是我得到了同样的错误。
Response := TStringStream.Create;
DS := TIdMultiPartFormDataStream.Create;
DS.AddFile('fileUpload2', 'C:\Users\r.rezino\Desktop\teste.po', 'multipart/form-data');
try
FHttpComunication.Request.ContentType := 'multipart/form-data';
FHttpComunication.Put(UrlCmd, DS, Response);
Result := Response.DataString;
finally
Response.Free;
DS.Free;
end;
2) 答案中建议的方式,但它不起作用。我也收到错误 500
。
PutData := TFileStream.Create('C:\Users\r.rezino\Desktop\teste.po', fmOpenRead or fmShareDenyWrite);
Response := TStringStream.Create;
try
FHttpComunication.Request.ContentType := 'multipart/form-data'; //I tried with and without it
FHttpComunication.Put(UrlCmd, PutData, Response);
Result := Response.DataString;
finally
Response.Free;
PutData.Free;
end;
API 被设计破坏了。你不应该混用 multipart/form-data
和 PUT
。你应该这样发送
FPutData:=TFileStream.Create('yourfile.dat', fmOpenRead or fmShareDenyWrite);
FHTTP.Put('http://...', FPutData, FResponseStream);
但如果不行,问题可能是你没有设置正确的ContentType
,它不包括边界。像这样修复它
FHTTP.Request.ContentType:=DS.RequestContentType;
其中 DS
是您的 TIdMultiPartFormDataStream
。
我发现了问题。这是关于我必须设定的界限。所以最后的结果是:
DS := TIdMultiPartFormDataStream.Create;
DS.AddFile('fileUpload2', 'C:\Users\r.rezino\Desktop\teste.po', 'application/octet-stream');
try
FHttpComunication.Request.ContentType := 'multipart/form-data; boundary=' + DS.Boundary;
FHttpComunication.Request.AcceptEncoding := '';
FHttpComunication.Request.Accept := '';
FHttpComunication.Request.Host := '';
FHttpComunication.Request.UserAgent := '';
FHttpComunication.Put(UrlCmd, DS, Response);
finally
DS.Free;
Response.Free;
end;