Carregando HTML com XMLHttpRequest - JavaScript
Frequentemente, em um código de página, é necessário obter algum código HTML do servidor. Por exemplo, uma página pode ser um site de uma única página que carrega o código HTML necessário através de uma solicitação AJAX e o insere na página. Portanto, vamos examinar como carregar código HTML via AJAX.
Para o servidor, assim como no tema anterior, usaremos Node.js como a opção mais simples, mas, naturalmente, qualquer outra tecnologia de servidor ou servidor web pode ser usada.
Então, vamos definir uma pasta no disco rígido para o projeto, onde criaremos três arquivos:
: a página principal da aplicaçãoindex.html
: a página com o código HTML que carregaremos via AJAXhome.html
: o arquivo da aplicação de servidor que usará Node.jsserver.js
Definindo o Servidor
O arquivo server.js
const http = require("http");
const fs = require("fs");
http.createServer((request, response) => {
// Obtendo o caminho após a barra, a barra é o primeiro caractere no caminho
let filePath = request.url.substring(1);
// Se o caminho estiver vazio, enviamos a página principal index.html
if (!filePath) filePath = "index.html";
// Definimos o tipo de resposta como HTML
response.setHeader("Content-Type", "text/html; charset=utf-8;");
fs.readFile(filePath, (error, data) => {
if (error) { // Em caso de erro
response.statusCode = 404;
response.end("Recurso não encontrado!
");
} else {
response.end(data);
}
});
}).listen(3000, () => console.log("Servidor iniciado em http://localhost:3000"));
Vamos examinar o código em detalhes. Primeiro, são importados os pacotes com funcionalidades que utilizaremos:
const http = require("http"); // Para lidar com solicitações recebidas
const fs = require("fs"); // Para ler arquivos do disco rígido
Para criar o servidor, usamos a função http.createServer()
request
response
Na função de callback, podemos obter o caminho do recurso solicitado através da propriedade request.url
let filePath = request.url.substring(1);
No entanto, se a solicitação for para a raiz do site, o caminho consistirá apenas de uma barra - "/". Nesse caso, se removermos essa barra, teremos uma string vazia. Portanto, se a solicitação for para a raiz da aplicação web, consideraremos que a solicitação é para a página principal - index.html:
if (!filePath) filePath = "index.html";
Como a resposta do servidor será código HTML, usamos o método setHeader()
response.setHeader("Content-Type", "text/html; charset=utf-8;");
Em seguida, usamos a função fs.readFile
data
fs.readFile(filePath, (error, data) => {
if (error) { // Em caso de erro
response.statusCode = 404;
response.end("Recurso não encontrado!
");
} else {
response.end(data);
}
});
Por fim, usamos a função listen()
http://localhost:3000
}).listen(3000, () => console.log("Servidor iniciado em http://localhost:3000"));
Definindo o Código HTML para Carregamento
O arquivo home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Home Page</title>
</head>
<body>
<h1>Home Page</h1>
<p>Home Page Text</p>
</body>
</html>
Definindo a Página Principal e Carregando Dados
Agora, definiremos o código da página principal index.html
home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Programício</title>
</head>
<body>
<script>
const xhr = new XMLHttpRequest();
xhr.onload = () => { // Handler para receber a resposta do servidor
if (xhr.status == 200) { // Se o código de resposta for 200
const html = xhr.responseText; // Obtemos a resposta
console.log(html); // Exibimos a resposta no console do navegador
} else { // Caso contrário, exibimos o status da resposta
console.log("Resposta do servidor: ", xhr.statusText);
}
};
xhr.open("GET", "/home.html"); // Solicitação GET para o recurso /home.html
xhr.setRequestHeader("Accept", "text/html"); // Aceitamos apenas HTML
xhr.send(); // Enviamos a solicitação
</script>
</body>
</html>
No handler de carregamento xhr.onload
xhr.responseText
Agora, no console, navegue até a pasta do servidor usando o comando cd
node server.js
C:\app>node server.js Servidor iniciado em http://localhost:3000
Após iniciar o servidor, podemos acessar o endereço http://localhost:3000
home.html

Gerenciando o Conteúdo HTML
No exemplo anterior, obtivemos o conteúdo da página como texto simples. No entanto, como esse texto contém marcação HTML, podemos carregá-lo na página web. Assim, vamos modificar o código da página index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Programício</title>
</head>
<body>
<div id="content"></div>
<script>
const contentDiv = document.getElementById("content"); // Elemento para carregar HTML
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status == 200) {
contentDiv.innerHTML = xhr.responseText; // Exibimos a resposta recebida em contentDiv
} else { // Caso contrário, exibimos o texto do status
console.log("Resposta do servidor: ", xhr.statusText);
}
};
xhr.open("GET", "/home.html"); // Solicitação GET para o recurso /home.html
xhr.setRequestHeader("Accept", "text/html"); // Aceitamos apenas HTML
xhr.send(); // Enviamos a solicitação
</script>
</body>
</html>
Neste caso, carregamos o código da página home.html no elemento com id="content"

No entanto, o problema aqui é que o código da página home.html
head
title
<meta />
home.html
responseXML
const contentDiv = document.getElementById("content");
const xhr = new XMLHttpRequest();
xhr.onload = () => { // Handler para receber a resposta do servidor
if (xhr.status == 200) {
// Carregamos apenas o conteúdo do elemento body
contentDiv.innerHTML = xhr.responseXML.body.innerHTML;
} else {
console.log("Resposta do servidor: ", xhr.statusText);
}
};
xhr.open("GET", "/home.html"); // Solicitação GET para o recurso /home.html
xhr.responseType = "document"; // Definimos o tipo de resposta
xhr.setRequestHeader("Accept", "text/html"); // Aceitamos apenas HTML
xhr.send(); // Enviamos a solicitação
Aqui, é importante observar dois pontos. Primeiro, definimos o tipo de resposta como "document":
xhr.responseType = "document";
Isso nos permite obter a resposta como um objeto do tipo Document
document
Para obter a resposta em formato HTML/XML, usamos a propriedade responseXML
Document
body
contentDiv.innerHTML = xhr.responseXML.body.innerHTML;
Como resultado, o conteúdo do elemento body
home.html
contentDiv
Da mesma forma, podemos acessar outras propriedades do objeto Document
document.title = xhr.responseXML.title;
Ou para carregar na página apenas o texto do título <h1>
contentDiv.innerHTML = xhr.responseXML.querySelector("h1").textContent;
Carregamento Dinâmico de Componentes
A capacidade de carregar código HTML e inseri-lo na página nos permite ir além e dividir a funcionalidade da aplicação em vários componentes, carregando-os conforme necessário. Por exemplo, vamos supor que no projeto temos os seguintes arquivos:
: arquivo da aplicação do servidor em Node.jsserver.js
: página principal da aplicaçãoindex.html
: arquivo do componente homehome.html
: arquivo do componente aboutabout.html
: arquivo do componente contactcontact.html
O arquivo da aplicação do servidor em Node.js, server.js
O arquivo home.html
<h1>Home Page</h1>
<p>Home Page Text</p>
O arquivo about.html
<h1>About Page</h1>
<p>About Page Text</p>
E o código do arquivo contact.html
<h1>Contact Page</h1>
<p>Contact Page Text</p>
Esses arquivos representam componentes que serão carregados na página principal.
Na página principal index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Programício</title>
</head>
<body>
<nav>
<a href="home">Home</a> |
<a href="about">About</a> |
<a href="contact">Contact</a>
</nav>
<div id="content"></div>
<script>
const contentDiv = document.getElementById("content");
function loadContent(fileName) {
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status == 200) {
contentDiv.innerHTML = xhr.responseText;
document.title = fileName;
} else {
console.log("Resposta do servidor: ", xhr.statusText);
}
};
xhr.open("GET", fileName + ".html");
xhr.setRequestHeader("Accept", "text/html");
xhr.send();
}
// Configura o handler de clique para os links
const links = document.getElementsByTagName("a");
for (let i = 0; i < links.length; i++) {
links[i].addEventListener("click", (e) => {
loadContent(links[i].getAttribute("href"));
e.preventDefault();
});
}
// Carrega o componente home por padrão
loadContent("home");
</script>
</body>
</html>
Aqui, para a navegação entre os componentes, colocamos uma série de links na página:
<nav>
<a href="home">Home</a> |
<a href="about">About</a> |
<a href="contact">Contact</a>
</nav>
O endereço de cada link coincide com o nome da página do componente correspondente, sem a extensão ".html".
Cada um dos componentes será carregado na página dentro do elemento com id="content"
contentDiv
const contentDiv = document.getElementById("content");
No código JavaScript, configuramos um handler para cada link, onde chamamos a função loadContent
href
const links = document.getElementsByTagName("a");
for (let i = 0; i < links.length; i++) {
links[i].addEventListener("click", (e) => {
loadContent(links[i].getAttribute("href"));
e.preventDefault();
});
}
Na função loadContent
contentDiv
contentDiv.innerHTML = xhr.responseText;
Ao carregar a página, carregamos imediatamente o código do componente home
loadContent("home");
Dessa forma, na página principal, podemos acessar componentes específicos clicando nos links:


