Numa primeira olhada, a utilidade do HTTP não parece muito diferente do FTP usado para fazer downloads. O código abaixo, por exemplo, obtém o documento padrão do site do Google Brasil, isto é, a página HTML que é exibida quando se digita o endereço do Google Brasil num navegador. No exemplo, estou usando o componente TIdHTTP da paleta do projeto Indy:
var lResponse : TStringStream;
begin
lResponse := TStringStream.Create('');
try
{ lResponse conterá a página HTML requisitada :}
idHttp1.Get('http://www.google.com.br', lResponse);
finally
lResponse.Free();
end;
Apesar de não ser necessário configurar explicitamente um servidor/porta e usuário/senha como no FTP, o resultado final é o mesmo: o download de um arquivo remoto. Na verdade, a infraestrutura da internete mapeia automaticamente o endereço do Google para um servidor/porta; nesse caso, o usuário e senha é dispensável pois se trata de um site público que permite acesso anônimo.begin
lResponse := TStringStream.Create('');
try
{ lResponse conterá a página HTML requisitada :}
idHttp1.Get('http://www.google.com.br', lResponse);
finally
lResponse.Free();
end;
Se olharmos mais a fundo, no entanto, veremos que o HTTP é mais flexível porque permite adicionar parâmetros à requisição enviada ao servidor. Na prática, isso dá ao servidor a chance de montar dinamicamente a resposta mais adequada à solicitação feita. As APIs de serviços publicados na internete normalmente são baseados no HTTP e se valem dos parâmetros pra flexibilizar as requisições. É o caso, por exemplo, do Google Docs e de outros serviços do Google, que usam a API de dados da empresa. Em outro post, eu mostro como se comunicar com o Google Docs usando a API de dados para ler os documentos salvos nesse serviço.
Se você já trabalhou com HTML, deve ter notado que a sintaxe dos Forms inclui uma "action", um método de envio e os diversos campos que serão preenchidos pelo usuário da página, sendo admitido até mesmo a existência de campos invisíveis contendo informações pré alimentadas.
Para relembrar o significado dessas propriedades do Form HTML : A "action" é o endereço na internete para onde a requisição será submetida. O "método" diz repespeito a como e quais informações serão enviadas; os valores mais comuns são GET (as informações são formatadas e acrescentadas ao endereço da "action", que então é enviado ao servidor) ou POST (as informações são transportadas à parte e não é possível enxergá-las na barra de endereço do navegador).
O form de pesquisa do Google, por exemplo, admite que você selecione a língua na qual deseja obter as repostas e, claro, os termos a serem pesquisados. O exemplo abaixo submete ao Google uma pesquisa em português com o nome do blog:
var lURL : String;
lResponse : TStringStream;
begin
lResponse := TStringStream.Create('');
try
lURL := 'http://www.google.com.br/search?' +
'hl=pt-BR&' +
'q=balaio%20tecnologico';
idHttp1.Get(lURL, lResponse);
lResponse.Position := 0;
{ Exemplo de uso do response : carregar o conteúdo num RichEdit : }
reResp.Lines.LoadFromStream(lResponse);
finally
lResponse.Free();
end;
Veja que cada parâmetro é composto de um nome (o mesmo configurado nas tags input do form) seguido por um sinal de igual (=) e o valor que o parâmetro deve assumir (normalmente, os próprios valores fornecidos pelo usuário). Cada parâmetro é concatenado ao anterior através de um "E Comercial" (&).lResponse : TStringStream;
begin
lResponse := TStringStream.Create('');
try
lURL := 'http://www.google.com.br/search?' +
'hl=pt-BR&' +
'q=balaio%20tecnologico';
idHttp1.Get(lURL, lResponse);
lResponse.Position := 0;
{ Exemplo de uso do response : carregar o conteúdo num RichEdit : }
reResp.Lines.LoadFromStream(lResponse);
finally
lResponse.Free();
end;
Ambos os parâmetros considerados pelo exemplo estão incluídos no form da pesquisa do Google. Ou seja, se você souber quais são os parâmetros de um form, poderá simular via Delphi a requisição que ele submeteria numa página da Web e, então, obter exatamente a mesma reposta, podendo tratá-la do modo que for mais apropriado para sua aplicação.
Por causa dessa facilidade de simular requisições via programação, muitos sites se protegem implementando um CAPTCHA. Trata-se de uma imagem com um texto embutido que é gerada dinamicamente pelo servidor de modo que apenas operadores humanos consigam ler. O texto deve, então, ser digitado num campo e enviado junto com as demais informações. A requisição só é atendida se o texto estiver correto.
Como podemos notar pelo exemplo, usar o GET para recuperar um documento pode ser problemático se certas informações sensíveis - como uma senha - tiverem que ser transmitidas direto na URL. Nestes casos, é recomendado usar o POST pois com ele as informações trafegam por outros meios.
O uso do POST também é simples. Basta passar os parâmetros num TStringList separado. A URL do "action" é informada sem quaisquer decorações extras:
var lParams :TStringList;
lResponse : TStringStream;
begin
lParams := TStringList.Create;
lResponse := TStringStream.Create('');
try
lParams.Add('filt=all');
lParams.Add('p=balaio%20tecnologico');
idHttp1.Post('http://br.search.yahoo.com/search', lParams, lResponse);
{ Exemplo de uso do response : carregar o conteúdo num RichEdit : }
lResponse.Position := 0;
reResp.Lines.LoadFromStream(lResponse);
finally
lParams.Free();
lResponse.Free();
end;
Neste exemplo, usei o Yahoo! porque o Google não implementa POST para pesquisas.lResponse : TStringStream;
begin
lParams := TStringList.Create;
lResponse := TStringStream.Create('');
try
lParams.Add('filt=all');
lParams.Add('p=balaio%20tecnologico');
idHttp1.Post('http://br.search.yahoo.com/search', lParams, lResponse);
{ Exemplo de uso do response : carregar o conteúdo num RichEdit : }
lResponse.Position := 0;
reResp.Lines.LoadFromStream(lResponse);
finally
lParams.Free();
lResponse.Free();
end;
Ajustes ainda mais finos para submeter a requisição podem ser configuras na propriedade Request do TIdHTTP. Com ele, é possível ajustar o tipo de documento que se espera receber de volta (HTML, XML, etc.), o tipo de encoding, se há necessidade de passar por um proxy, etc.

Se eu coloco o site para abrir a partir de um edit da Unknown Protocol, como contorno?
ResponderExcluirVocê colocou uma caixa de texto (edit) na tela para o usuário poder entrar com o endereço do site? Neste caso, certifique-se de que o endereço digitado está completo, incluindo o "http" no início. Os navegadores hoje acrescentam isso automaticamente mas chamadas via API (como as do post) não. Então, se o usuário não passar isso no seu edit, o seu programa pode completá-lo antes de chamar get ou post.
Excluir[]s
No caso seria correto eu criar o idHttp dentro da thread ou quando chamo na unit principal? Caso eu queria fazer vários downloads.
ResponderExcluirNo caso algo como:
Crio o idhttp
crio a thread indicando o idhttp criado.
E quando terminar o downlaod eu dou um free na thread?
Como vou identificar a thread correta se eu uso a mesma variável para todas as threads?
O TidHTTP não precisa estar embutido num TForm. Por isso, você pode criar o TidHTTP como um membro da sua thread e instanciá-lo manualmente, evitando a necessidade de sincronizar o uso do recurso compartilhado.
ExcluirSe você tem alguma restrição para criar mais que um TidHTTP, dê veja o post Trabalhando com Threads em Delphi - Seções Críticas. Nele há exemplos de sincronização no uso de recursos compartilhados em ambiente multi-thread.
[]s
Luis, utilizei a tua sugestão de rotina para buscar o retorno de uma url que no caso o retorno é um xml, ao executar:
ResponderExcluirIdHTTPxml.get('urldoclientecomparametros',lresponse);
XMLresposta.Active := True;
XMLresposta.Encoding := 'iso-8859-1';
XMLresposta.LoadFromStream(lResponse);
Não está vendo como um xml e sim apenas dividindo em duas linhas, sendo a segunda todo o conteudo do xml como um texto. O que pode estar errado ?
Você consegue enxergar o XML de retorno no navegador(IE, Firefox ou Chrome) ? Isto é, ao invés de carregar no TDomXml, salve o retorno para um arquivo e veja se o navegador consegue abrí-lo corretamente.
ExcluirPS:Não tenho certeza mas talvez vc precise voltar a posição do lResponse para o começo do stream antes de carrega-lo no XMLResposta. Algo como lResponse.Position := 0;
[]s
Sobre o comentario anterior, queria adicionar o seguinte. qdo visualizo o codigo fonte do retorno desta URL, realmente volta todo o xml em uma unica linha.
ResponderExcluir