我正在尝试使用TIdHTTP.Get()函数与网络中继通信。
根据他们的文档,来自Web Relay的每个XML响应都是157字节长。下面是一个WebRelay单元的示例XML响应,该单元的输入为off,中继状态为on。
<?xml version='1.0' encoding='utf-8'?>
<datavalues>
<relaystate>1</relaystate>
<inputstate>0</inputstate>
<rebootstate>0</rebootstate>
</datavalues>我得到了一个E.ErrorMessage为</datavalues>的EIdHTTPProtocolException。
下面是我的代码:
var
get_url, Response: string;
begin
Memo1.Lines.Clear;
IdHTTP.Request.Username := 'admin'; // User
IdHTTP.Request.Password := 'webrelay'; // Password
IdHTTP.Request.BasicAuthentication := true; //Auth. BASIC
try
get_url := 'http://144.129.139.172 /state.xml';
response := IdHTTP.Get(get_url);
Memo1.lines.add(response);
except
on E: EIdHTTPProtocolException do
Memo2.lines.add(E.ErrorMessage);
end;
end;发布于 2021-09-17 17:37:00
根据您在注释中提供的日志,Web Relay没有使用HTTP1.x作为响应,而是使用TIdHTTP does not currently support代替HTTP 0.9。
在野外,HTTP服务器对User-Agent请求头敏感的情况并不少见,它们为不同的web浏览器提供不同类型的数据。一些真实的HTTP服务器无法识别Indy的默认User-Agent,因此会以奇怪的方式处理它们的响应,并且以前已经观察到使用HTTP0.9来响应TIdHTTP (尽管很少)。
因此,您应该尝试的第一件事是将TIdHTTP.Request.UserAgent属性设置为模拟真实web浏览器的值,例如:
var
get_url, Response: string;
begin
Memo1.Lines.Clear;
IdHTTP.Request.Username := 'admin'; // User
IdHTTP.Request.Password := 'webrelay'; // Password
IdHTTP.Request.BasicAuthentication := true; //Auth. BASIC
// ADD THIS (use whatever UA you want, as long as it is real)...
IdHTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0';
try
get_url := 'http://144.129.139.172/state.xml';
Response := IdHTTP.Get(get_url);
Memo1.Lines.Add(Response);
except
on E: EIdHTTPProtocolException do
Memo2.Lines.Add(E.ErrorMessage);
end;
end;如果这不能使Web Relay使用HTTP 1.x进行响应,那么您应该联系Web Relay的管理员以获得帮助。如果Web Relay不能使用HTTP1.x响应,您将无法使用TIdHTTP与其通信,句号。在这种情况下,您将不得不使用TIdTCPClient,发送自己的超文本传输协议请求,这样您就可以读取整个XML,例如:
var
Response: string;
begin
Memo1.Lines.Clear;
try
IdTCPClient1.Host := '144.129.139.172';
IdTCPClient1.Port := 80;
IdTCPClient1.Connect;
try
with IdTCPClient1.IOHandler do
begin
WriteLn('GET /state.xml HTTP/1.0');
WriteLn('Host: ' + IdTCPClient1.Host);
WriteLn('Accept: */*');
WriteLn('User-Agent: ...');
WriteLn('Authorization: Basic ' + TIdEncoderMIME.EncodeString('admin:webrelay', IndyTextEncoding_UTF8));
WriteLn;
Response := AllData;
end;
finally
IdTCPClient1.Disconnect;
end;
Memo1.Lines.Add(Response);
except
on E: Exception do
Memo2.Lines.Add(E.Message);
end;
end;https://stackoverflow.com/questions/69225556
复制相似问题