HttpWebRequest使用GET重定向而不是像idHttp一样使用POST

时间:2015-01-16 18:18:09

标签: c# delphi httpwebrequest

抱歉我的英文。

在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;

2 个答案:

答案 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,而不是相反。