抱歉我的英文。
在Delphi中,我有一个idHttp组件,激活了hoWaitForUnexpectedData选项。
当我向URL发送POST请求时,它会将客户端重定向到具有相同POST请求和标头的第二个URL。此外,服务器响应在其标题中包含“Connection:keep-alive”。
但是,当我尝试使用HttpWebRequest组件在C#中执行相同的请求时,它会使用方法GET重定向到第二个URL。
我需要C#HttpWebRequest组件像Delphi idHTTP一样工作。我不明白为什么它在遵循重定向时使用GET而不是POST。
这是我在Delphi中的代码,使用hoWaitForUnexpectedData:
// The server is supposed to send a 'Content-Length' header without sending
// the actual data. 1xx, 204, and 304 replies are not supposed to contain
// entity bodies, either...
if TextIsSame(ARequest.Method, Id_HTTPMethodHead) or
TextIsSame(ARequest.MethodOverride, Id_HTTPMethodHead) or
((AResponse.ResponseCode div 100) = 1) or
(AResponse.ResponseCode = 204) or
(AResponse.ResponseCode = 304) then
begin
// Have noticed one case where a non-conforming server did send an
// entity body in response to a HEAD request. If requested, ignore
// anything the server may send by accident
if not (hoWaitForUnexpectedData in FOptions) then begin
Exit;
end;
Result := CheckForPendingData(100);
end
else if (AResponse.ResponseCode div 100) = 3 then
begin
// This is a workaround for buggy HTTP 1.1 servers which
// does not return any body with 302 response code
Result := CheckForPendingData(5000);
end else begin
Result := True;
end;
答案 0 :(得分:2)
根据标准的定义,应使用GET处理HTTP重定向。因此,如果您发送POST并获得重定向作为答案,则预期的行为是对重定向地址执行GET。我怀疑旧的Delphi组件是遵循旧的做法并复制调用,包括使用POST动词。
我会尝试在HttpWebRequest对象中禁用AllowAutoRedirect并手动处理,因为您的情况似乎与标准不同。
答案 1 :(得分:1)
hoWaitForUnexpectedData
选项对TIdHTTP
处理重定向的方式没有影响,您引用的代码部分也没有影响。
但是,hoTreat302Like303
选项确实会影响重定向处理。如果TIdHTTP
收到303
重定向,或收到启用了302
的{{1}}重定向,则hoTreat302Like303
会将新请求作为TIdHTTP
发送。否则,它使用与重定向请求相同的动词发送新请求。这是设计的,GET
方法的实现代码中有一系列注释解释了这种行为背后的理性:
TIdHTTPProtocol.ProcessResponse()
它的主旨是HTTP规范要求为 // GDG 21/11/2003. If it's a 303, we should do a get this time
// RLebeau 7/15/2004 - do a GET on 302 as well, as mentioned in RFC 2616
// RLebeau 1/11/2008 - turns out both situations are WRONG! RFCs 2068 and
// 2616 specifically state that changing the method to GET in response
// to 302 and 303 is errorneous. Indy 9 did it right by reusing the
// original method and source again and only changing the URL, so lets
// revert back to that same behavior!
// RLebeau 12/28/2012 - one more time. RFCs 2068 and 2616 actually say that
// changing the method in response to 302 is erroneous, but changing the
// method to GET in response to 303 is intentional and why 303 was introduced
// in the first place. Erroneous clients treat 302 as 303, though. Now
// encountering servers that actually expect this 303 behavior, so we have
// to enable it again! Adding an optional HTTPOption flag so clients can
// enable the erroneous 302 behavior if they really need it.
重定向发送GET
,而对于303
是否发送GET
则不明确。有些浏览器有,有些则没有。这就是添加302
选项的原因,但默认情况下它被禁用,以便与早期的Indy版本向后兼容。
因此,您描述的行为意味着您必须遇到hoTreat302Like303
重定向,并禁用302
(默认情况下)。如果您启用该选项,hoTreat302Like303
的行为将更像TIdHTTP
,而不是相反。