You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用TIdHTTP.Get()访问Web Relay时出现EIdHTTPProtocolException异常

异常触发原因及解决方案

触发原因

  1. URL存在语法错误:代码中定义的get_url参数里,IP地址144.129.139.172和路径/state.xml之间存在多余空格,属于非法请求格式。Web Relay属于嵌入式设备,HTTP服务实现不标准,收到非法请求时不会返回标准HTTP错误响应头,只会返回不完整的XML内容,同时返回的HTTP状态码不属于2xx成功范围,触发Indy组件的EIdHTTPProtocolException异常。
  2. TIdHTTP默认规则限制:TIdHTTP默认会将所有非2xx段的HTTP状态码判定为异常并抛出,而Web Relay这类嵌入式硬件的HTTP服务即使返回了正常的XML内容,也常出现状态码设置错误、Content-Length字段与实际响应长度不匹配的问题,导致Indy判定为协议错误,此时异常的ErrorMessage会存储最后接收到的响应片段,也就是你捕获到的</datavalues>。

解决方案

  • 首先修正URL语法错误,删除IP和路径之间的多余空格:
    get_url := 'http://144.129.139.172/state.xml';
    
  • 调整TIdHTTP配置,关闭非必要的协议异常抛出规则,添加如下配置代码:
    IdHTTP.HTTPOptions := IdHTTP.HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];
    
    两个参数的作用分别是:收到非2xx状态码时不抛出异常、将异常响应内容也正常返回给调用方,你可以直接接收返回内容自行解析XML,不需要通过异常捕获逻辑获取内容。
  • 可选优化:如果仍存在编码识别问题,可以改用TMemoryStream接收响应,避免字符串转码误差,完整示例代码如下:
    var
      get_url: string;
      ResponseStream: TMemoryStream;
      ResponseStr: string;
    begin
      Memo1.Lines.Clear;
      ResponseStream := TMemoryStream.Create;
      try
        IdHTTP.Request.Username := 'admin';
        IdHTTP.Request.Password := 'webrelay';
        IdHTTP.Request.BasicAuthentication := True;
        // 关闭协议异常抛出
        IdHTTP.HTTPOptions := IdHTTP.HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];
        // 修正后的合法URL
        get_url := 'http://144.129.139.172/state.xml';
        IdHTTP.Get(get_url, ResponseStream);
        // 按设备指定的utf-8编码将流转为字符串
        SetString(ResponseStr, PAnsiChar(ResponseStream.Memory), ResponseStream.Size);
        Memo1.Lines.Add(ResponseStr);
      finally
        ResponseStream.Free;
      end;
    end;
    

内容的提问来源于stack exchange,提问作者TBlanc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 03:06:02