5. Ejemplo de servicio

Versión para imprimir.

A. Introducción

En esta lección se explica el funcionamiento de un servicio muy sencillo.

Puedes probar el ejemplo en http://srvejemplo.rf.gd/.

B. Diagrama de despliegue

Diagrama de despliegue

C. Funcionamiento

Versión para imprimir.

1. Iniciamos al ejecutar código en el cliente

index.html

const respuesta =
 await fetch("servicio.php")
if (respuesta.ok) {
 const texto =
  await respuesta.text()
 alert(texto)
} else {
 throw new Error(
  respuesta.statusText)
}

2. Se invoca el servicio en el servidor

index.html

const respuesta =
 await fetch("servicio.php")
if (respuesta.ok) {
 const texto =
  await respuesta.text()
 alert(texto)
} else {
 throw new Error(
  respuesta.statusText)
}

Ejecuta fetch y envía request (solicitud).

Request

GET /servicio.php HTTP/1.1 Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: es-MX,es-ES;q=0.9,es;q=0.8,en;q=0.7,gl;q=0.6,pt;q=0.5
Connection: keep-alive
Cookie: __test=05fe05fbd9badf84bcd27287a4645c00
Host: srvejemplo.rf.gd
Referer: https://srvejemplo.rf.gd/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36
sec-ch-ua: "Chromium";v="148", "Google Chrome";v="148", "Not/A)Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"

servicio.php

<?php

echo "Hola";

Despierta y recibe request.

3. El servicio procesa la request y genera la response

index.html

const respuesta =
 await fetch("servicio.php")
if (respuesta.ok) {
 const texto =
  await respuesta.text()
 alert(texto)
} else {
 throw new Error(
  respuesta.statusText)
}

Hace wait esperando response.

servicio.php

<?php

echo "Hola";

Procesa la request y genera
la response (respuesta).

Response

HTTP/1.1 200 OK Server: openresty
Date: Fri, 15 May 2026 21:02:57 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: max-age=0
Expires: Fri, 15 May 2026 21:02:57 GMT
Hola

El code (o código) 200
indica que terminó
con éxito.

4. El servicio devuelve la response, que es recibida en el cliente

index.html

const respuesta =
 await fetch("servicio.php")
if (respuesta.ok) {
 const texto =
  await respuesta.text()
 alert(texto)
} else {
 throw new Error(
  respuesta.statusText)
}

Despierta y recibe response.

Response

HTTP/1.1 200 OK Server: openresty
Date: Fri, 15 May 2026 21:02:57 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: max-age=0
Expires: Fri, 15 May 2026 21:02:57 GMT
Hola

Memoria

resp
ok
true
text
Hola

resp tiene lo mismo
que la response,
pero en un objeto
de JavaScript.

servicio.php

<?php

echo "Hola";

Devuelve response y se duerme.

5. Verifica si la conexión terminó con éxito

index.html

const respuesta =
 await fetch("servicio.php")
if (respuesta.ok) {
 const texto =
  await respuesta.text()
 alert(texto)
} else {
 throw new Error(
  respuesta.statusText)
}

Memoria

resp
ok
true
text
Hola

6. Como la conexión terminó con éxito, recupera el texto de response

index.html

const respuesta =
 await fetch("servicio.php")
if (respuesta.ok) {
 const texto =
  await respuesta.text()
 alert(texto)
} else {
 throw new Error(
  respuesta.statusText)
}

Memoria

resp
ok
true
text
Hola
texto
Hola

El texto recuperado
queda en la
constante texto.

7. Muestra el texto en un alert

index.html

const respuesta =
 await fetch("servicio.php")
if (respuesta.ok) {
 const texto =
  await respuesta.text()
 alert(texto)
} else {
 throw new Error(
  respuesta.statusText)
}

Memoria

resp
ok
true
text
Hola
texto
Hola

Alert

Hola

8. Al cerrar el alert, termina el evento

index.html

const respuesta =
 await fetch("servicio.php")
if (respuesta.ok) {
 const texto =
  await respuesta.text()
 alert(texto)
} else {
 throw new Error(
  respuesta.statusText)
}

D. Contenido de una solicitud

GET /servicio.php HTTP/1.1
Es la instrucción principal. El navegador está pidiendo leer (método GET) el archivo servicio.php utilizando la versión 1.1 del protocolo HTTP.
Accept
*/*
El navegador indica que puede entender y recibir cualquier tipo de archivo o formato de datos (texto, imágenes, JSON, HTML, etc.).
Accept-Encoding
gzip, deflate, br, zstd
Lista los formatos de compresión que el navegador soporta. El servidor puede usar uno de estos (como gzip o br - Brotli) para comprimir la respuesta y hacer que cargue más rápido.
Accept-Language
es-MX,es-ES;q=0.9,es;q=0.8,en;q=0.7,gl;q=0.6,pt;q=0.5
Son los idiomas que prefiere el usuario. El orden y el valor q (peso) indican la prioridad: prefiere español de México, luego español de España, luego español general, gl es gallego y pt es portugués.
Connection
keep-alive
Le pide al servidor que mantenga la conexión de red abierta después de enviar esta respuesta. Esto ahorra tiempo si el navegador necesita pedir más archivos (como imágenes o scripts) en los siguientes segundos.
Host
srvejemplo.rf.gd
Especifica a qué dominio de internet va dirigida la petición. Es vital porque un mismo servidor físico puede alojar muchas páginas web diferentes.
Cookie
__test=05fe05fbd9badf84bcd27287a4645c00
Envía un pequeño dato temporal que el servidor guardó previamente en el navegador. Se usa para mantener la sesión del usuario o recordar información entre páginas.
Referer
https://srvejemplo.rf.gd/
Le dice al servidor de dónde viene el usuario. En este caso, la petición se disparó mientras el usuario estaba en esa URL exacta.
Sec-Fetch-Dest
empty
Indica que el resultado de la petición no se va a inyectar directamente en el navegador (como pasaría con un <script> o un <iframe>). Suele significar que es una petición hecha por código JavaScript (por ejemplo, con fetch() o XMLHttpRequest).
Sec-Fetch-Mode
cors
Indica que es una solicitud de recursos que sigue las reglas CORS (Cross-Origin Resource Sharing), muy común en peticiones hechas por JavaScript.
Sec-Fetch-Site
same-origin
Confirma que la solicitud se está haciendo hacia el mismo dominio en el que el usuario ya se encuentra (no es una petición hacia un sitio externo de terceros).
User-Agent
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36
Es la forma clásica en la que el navegador dice qué es. Aquí indica que es Chrome versión 148 elaborado con Mozilla versión 5.0 para un sistema Windows 10.0 de 64 bits, con AppleWebKit versión 537.36 y Safari versión 537.36.
sec-ch-ua
"Chromium";v="148", "Google Chrome";v="148", "Not/A)Brand";v="99"
Es una versión moderna y más estructurada del User-Agent. Especifica la marca y versión exacta del motor del navegador.
sec-ch-ua-mobile
?0
Responde si el dispositivo es un teléfono móvil. El ?0 significa "Falso", por lo que es una computadora de escritorio o laptop.
sec-ch-ua-platform
"Windows"
Confirma que el sistema operativo del usuario es Windows.

E. Contenido de una respuesta

HTTP/1.1 200 OK
El navegador está utilizando la versión 1.1 del protocolo HTTP. 00 OK, que significa que la petición fue exitosa.
Server
openresty
Identifica el software que el servidor web está utilizando para procesar tu solicitud. En este caso es OpenResty, que es una plataforma web de alto rendimiento basada en Nginx.
Date
Fri, 15 May 2026 21:02:57 GMT
Es la fecha y hora exacta (en la zona horaria GMT) en la que el servidor generó esta respuesta.
Content-Type
text/html; charset=UTF-8
Le dice al navegador qué tipo de archivo está recibiendo y cómo debe interpretarlo. Aquí indica que es un documento web estándar (text/html) y que utiliza la codificación de caracteres UTF-8 (el estándar moderno que soporta casi todos los idiomas y símbolos).
Transfer-Encoding
chunked
Indica que el servidor no enviará el archivo de una sola vez con un tamaño total específico. En su lugar, lo dividirá y enviará en pequeños "fragmentos" (chunks). Esto es muy común en páginas generadas dinámicamente, ya que el servidor puede empezar a enviar la respuesta antes de haber terminado de construirla por completo.
Connection
keep-alive
El servidor acepta la petición del navegador de mantener la conexión TCP abierta. Esto permite que los siguientes archivos que el navegador necesite (como el archivo CSS, imágenes o JavaScript) se descarguen mucho más rápido por esa misma "tubería".
Cache-Control
max-age=0
Es una instrucción sobre cómo el navegador debe almacenar (o no) esta página en su memoria caché. max-age=0 significa que la página caduca en 0 segundos, por lo que el navegador debe verificar con el servidor si hay una versión actualizada antes de intentar mostrar una versión guardada en el futuro.
Expires
Fri, 15 May 2026 21:02:57 GMT
Es la forma antigua o clásica de manejar la caché. Indica la fecha y hora exactas en las que el contenido de esta respuesta se considera obsoleto. Si te fijas, la hora es exactamente la misma que la cabecera Date, lo que refuerza la orden de que el contenido caduca inmediatamente.

F. Hazlo funcionar (con videos)

  1. Prueba el ejemplo en http://srvejemplo.rf.gd/.

  2. Descarga el archivo /src/srvejemplo.zip y descompáctalo.

  3. Crea una cuenta de email pqra ti, por ejemplo, pepito@google.com. Si ya tienes un email, omite este paso,

  4. Crea una cuenta de GitHub usando el email anterior y selecciona el nombre de usuario unsando la parte inicial del correo electrónico, por ejemplo pepito. Si ya tienes una cuenta, omite este paso.

  5. Crea un repositorio nuevo. En el nombre del repositorio debes poner el nombre de tu sitio; por ejemplo servicio

  6. Importa el proyecto de GitHub a Visual Studio Code

  7. Edita los archivos que desees.

  8. Prueba tu sitio localmente.

  9. Necesitas un hosting. En este ejemplo se muestra como usar el hosting. https://infinityfree.com/ Si no lo has usado, lo primero que tienes que hacer es entrar a registrar tu email con el botón Registrar. Si ya tienes tu email registrado, omite este paso.

  10. Crea una cuenta y un dominio para el ejemplo y crea directamente los archivos. Si ya tienes cuenta, entra a ella y crea un nuevo dominio con sus archivos.

  11. Sube tus archivos a GitHub. En este ejemplo no necesitas esperar 11 o más minutos.

G. Hazlo funcionar (texto)

  1. Prueba el ejemplo en http://srvejemplo.rf.gd/.

  2. Descarga el archivo /src/srvejemplo.zip y descompáctalo.

  3. Crea tu proyecto en GitHub:

    1. Crea una cuenta de email para tí, por ejemplo, pepito@google.com. Si ya tienes un email, omite este paso.

    2. Crea una cuenta de GitHub usando el email anterior y selecciona el nombre de usuario unsando la parte inicial del correo electrónico, por ejemplo pepito. Si ya tienes una cuenta, omite este paso.

    3. Crea un repositorio nuevo. En la página principal de GitHub cliquea 📘 New.

    4. En la página Create a new repository introduce los siguientes datos:

      • Proporciona el nombre de tu repositorio debajo de donde dice Repository name *.

      • Mantén la selección Public para que otros usuarios puedan ver tu proyecto.

      • Verifica la casilla Add a README file. En este archivo se muestra información sobre tu proyecto.

      • Cliquea License: None. y selecciona la licencia que consideres más adecuada para tu proyecto.

      • Cliquea Create repository.

  4. Importa el proyecto en GitHub:

    1. En la página principal de tu proyecto en GitHub, en la pestaña < > Code, cliquea < > Code y en la sección Branches y copia la dirección que está en HTTPS, debajo de Clone.

    2. En Visual Studio Code, usa el botón de la izquierda para Source Control.

      Imagen de Source Control
    3. Cliquea el botón Clone Repository.

    4. Pega la url que copiaste anteriormente hasta arriba, donde dice algo como Provide repository URL y presiona la teclea Intro.

    5. Selecciona la carpeta donde se guardará la carpeta del proyecto.

    6. Abre la carpeta del proyecto importado.

    7. Añade el contenido de la carpeta descompactada que contiene el código del ejemplo.

  5. Edita los archivos que desees.

  6. Haz clic derecho en index.html, selecciona PHP Server: serve project y se abre el navegador para que puedas probar localmente el ejemplo.

  7. Para depurar paso a paso haz lo siguiente:

    1. En el navegador, haz clic derecho en la página que deseas depurar y selecciona inspeccionar.

    2. Recarga la página, de preferencia haciendo clic derecho en el ícono de volver a cargar la página Ïmagen del ícono de recarga y seleccionando vaciar caché y volver a cargar de manera forzada (o algo parecido). Si no aparece un menú emergente, simplemente cliquea volver a cargar la página Ïmagen del ícono de recarga. Revisa que no aparezca ningún error ni en la pestañas Consola, ni en Red.

    3. Selecciona la pestaña Fuentes (o Sources si tu navegador está en Inglés).

    4. Selecciona el archivo donde vas a empezar a depurar.

    5. Haz clic en el número de la línea donde vas a empezar a depurar.

    6. En Visual Studio Code, abre el archivo de PHP donde vas a empezar a depurar.

    7. Haz clic en Run and Debug .

    8. Si no está configurada la depuración, haz clic en create a launch json file.

    9. Haz clic en la flechita RUN AND DEBUG, al lado de la cual debe decir Listen for Xdebug .

    10. Aparece un cuadro con los controles de depuración

    11. Selecciona otra vez el archivo de PHP y haz clic en el número de la línea donde vas a empezar a depurar.

    12. Regresa al navegador, recarga la página y empieza a usarla.

    13. Si se ejecuta alguna de las líneas de código seleccionadas, aparece resaltada en la pestaña de fuentes. Usa los controles de depuración para avanzar, como se muestra en este video.

  8. Entra al hosting que elijas y añade directamente los archivos.

  9. Abre un navegador y prueba el proyecto en tu hosting.

  10. En el hosting InfinityFree, la primera vez que corres la página, puede marcar un mensaje de error, pero al recargar funciona correctamente. Puedes evitar este problema usando un dominio propio.

  11. Para subir el código a GitHub, en la sección de SOURCE CONTROL, en Message introduce un mensaje sobre los cambios que hiciste, por ejemplo index.html corregido, selecciona v y luego Commit & Push.

    Imagen de Commit & Push

H. Archivos

I. index.html

1
<!DOCTYPE html>
2
<html lang="es">
3
4
<head>
5
6
 <meta charset="UTF-8">
7
 <meta name="viewport" content="width=device-width">
8
9
 <title>Ejemplo de servicio</title>
10
11
</head>
12
13
<body>
14
 <h1>Ejemplo de servicio</h1>
15
16
 <button onclick="ejecuta()">
17
  Ejecuta
18
 </button>
19
20
 <script>
21
22
  async function ejecuta() {
23
   try {
24
    // Se conecta a servicio.php y recibe su respuesta.
25
    const respuesta =
26
     await fetch("servicio.php")
27
    if (respuesta.ok) {
28
     const texto =
29
      await respuesta.text()
30
     alert(texto)
31
    } else {
32
     throw new Error(
33
      respuesta.statusText)
34
    }
35
   } catch (error) {
36
    console.error(error)
37
    alert(error.message)
38
   }
39
  }
40
41
 </script>
42
43
</body>
44
45
</html>

J. servicio.php

1
<?php
2
3
echo "Hola";
4

K. Resumen