En 2005, Jesse James Garrett escribió un artículo "Ajax: un nuevo enfoque para las aplicaciones web", que describía una aplicación llamada Ajax (tecnología JavaScript asincrónica + XML). Esta técnica implica enviar al servidor una solicitud de datos adicionales sin actualizar la página, lo que resulta en una mejor experiencia del usuario. Garrett explica cómo esta tecnología cambia el modelo tradicional de hacer clic y esperar que ha persistido desde el nacimiento de la Web.
La tecnología clave que llevó a Ajax al escenario histórico es el objeto XMLHttpRequest (XHR). Antes de la llegada de XHR, la comunicación estilo Ajax tenía que lograrse a través de alguna tecnología negra, principalmente utilizando paneles ocultos o paneles en línea. XHR proporciona una interfaz razonable para enviar solicitudes al servidor y obtener respuestas. Esta interfaz puede obtener datos adicionales del servidor de forma asincrónica, lo que significa que los usuarios pueden obtener datos sin actualizar la página. Después de obtener datos a través del objeto XHR, puede utilizar métodos DOM para insertar los datos en la página web.
La API de objetos XHR generalmente se considera difícil de usar, y la API Fetch se convirtió rápidamente en un estándar alternativo más moderno para XHR después de su nacimiento automático. La API Fetch admite promesas programadas y subprocesos de servicio (trabajadores de servicio), y se ha convertido en una web extremadamente poderosa. herramienta de desarrollo.
Una limitación importante de la comunicación Ajax a través de XHR es la política de seguridad entre orígenes. De forma predeterminada, XHR solo puede acceder a recursos en el mismo dominio que la página que inició la solicitud. Esta restricción de seguridad previene ciertos comportamientos maliciosos. Sin embargo, los navegadores también deben admitir el acceso legal entre orígenes.
El intercambio de recursos entre orígenes (CORS) define cómo los navegadores y servidores implementan la comunicación entre orígenes. La idea básica detrás de CORS es utilizar encabezados HTTP personalizados para permitir que el navegador y el servidor se entiendan entre sí para determinar si una solicitud o respuesta debe tener éxito o fallar.
Para solicitudes simples, como solicitudes GET o POST, no hay encabezados personalizados y el cuerpo de la solicitud es de tipo texto/sin formato. Dichas solicitudes tendrán un encabezado adicional llamado Origen cuando se envíen. El encabezado Origen contiene la fuente (protocolo, nombre de dominio, puerto) de la página que envía la solicitud para que el servidor pueda determinar si debe proporcionar una respuesta.
Los navegadores modernos admiten CORS de forma nativa a través del objeto XMLHttpRequst, que se activa automáticamente al intentar acceder a recursos de diferentes orígenes. Para enviar una solicitud a un origen en un dominio diferente, puede usar un objeto XHR estándar y pasar una URL absoluta al método open(), por ejemplo:
let xhr = new XMLHttpRequest();xhr.onreadystatechange = function(){ si(xhr.readyState == 4){ if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alerta(xhr.reaponseText); }demás{ alert("La solicitud no tuvo éxito:"+xhr.status); } }};xhr.open("get","http://www.nezha.con/page/",true);xhr.send(null);
los objetos XHR entre dominios permiten el acceso a las propiedades status y statusText, y También permite la sincronización Las solicitudes de objetos XHR entre dominios también imponen algunas restricciones adicionales por razones de seguridad.
No puede usar setRequestHeader() para configurar encabezados personalizados;
no puede enviar ni recibir cookies;
el método getAllResponseHeaders() siempre devuelve una cadena vacía
porque se usa la misma interfaz para solicitudes del mismo dominio y entre dominios
;acceder a recursos locales Utilice URL relativas y URL absolutas al acceder a recursos remotos. Esto puede distinguir más claramente los escenarios de uso y evitar el problema del acceso restringido a la información del encabezado o de las cookies al acceder a recursos locales.
CORS utiliza un mecanismo de verificación del servidor llamado solicitud de verificación previa, que permite el uso de encabezados personalizados, métodos distintos de GET y POST, y diferentes tipos de contenido del cuerpo de la solicitud. Al enviar una solicitud que involucra una de las opciones avanzadas anteriores, primero se envía una solicitud de verificación previa al servidor. Esta solicitud se envía utilizando el método OPCIONES y contiene los siguientes encabezados:
Origen: lo mismo que una solicitud simple
Método de solicitud de control de acceso: el método que desea utilizar
Encabezados de solicitud de control de acceso: coma (opcional); -valores separados para usar Lista de encabezados personalizados
La Fetch API puede realizar todas las tareas del objeto XMLHttpRequest, pero es más fácil de usar, la interfaz es más moderna y se puede usar en herramientas web como Hilos de trabajadores web. XMLHttpRequest puede elegir ser asíncrono, mientras que la API Fetch debe ser asíncrona.
El método fetch() está expuesto en el ámbito global, incluido el hilo de ejecución de la página principal, los módulos y los hilos de trabajo. Llamar a este método hace que el navegador envíe una solicitud a la URL proporcionada.
1. Solicitud de envío
fetch() tiene solo una entrada de parámetro requerida. En la mayoría de los casos, este parámetro es la URL para obtener el recurso y este método devuelve una promesa:
let r = fetch('/bar');console.log(r);//Promise<pending>
Formato de URL (ruta relativa , rutas absolutas, etc.) se interpretan de la misma manera que los objetos XHR.
Cuando se complete la solicitud y los recursos estén disponibles, se procesará un objeto Respuesta. Este objeto es una encapsulación de la API a través de la cual se pueden obtener los recursos correspondientes. Utilice las propiedades y métodos de este objeto para obtener recursos, comprender la respuesta y convertir el equilibrio de carga en una forma útil.
2. Leer la respuesta La forma más sencilla de leer el contenido de la respuesta es obtener el contenido en formato de texto sin formato, simplemente use el método text(). Este método devuelve una promesa, que resuelve recuperar el contenido completo del recurso.
3. Manejo de códigos de estado y fallas de solicitud
La API Fetch admite la verificación del estado de la respuesta a través de las propiedades status y statusText de Response. Las solicitudes que obtienen una respuesta exitosa generalmente generan un código de estado con un valor de 200.
4. Modos de solicitud de recuperación comunes:
enviar datos JSON,
enviar parámetros en el cuerpo de la solicitud,
enviar archivos
, cargar archivos Blob
, enviar solicitudes entre dominios,
interrumpir solicitudes
socket El objetivo de websocket es lograr full-duplex y dos- comunicación con el servidor a través de una conexión a largo plazo. Al crear un websocket en JavaScript, se envía una solicitud HTTP al servidor para inicializar la conexión. Después de que el servidor responde, la conexión cambia del protocolo HTTP al protocolo websocket usando el encabezado Actualizar en HTTP, lo que significa que websocket no se puede implementar a través de un servidor HTTP estándar, sino que debe usar un servidor propietario que admita este protocolo.
Debido a que websocket usa un protocolo personalizado, el esquema de URL ha cambiado ligeramente. http:// o https:// ya no se pueden usar, pero se deben usar ws:// y wss://. La primera es una conexión insegura y la segunda es una conexión segura. Al ejecutar URL de websocket, se debe incluir el esquema de URL, ya que es posible que se admitan esquemas adicionales en el futuro.
La ventaja de utilizar un protocolo personalizado en lugar del protocolo HTTP es que el cliente y el servidor pueden enviar muy pocos datos sin causar ninguna carga a HTTP. El uso de paquetes de datos más pequeños hace que los websockets sean ideales para aplicaciones móviles donde los problemas de ancho de banda y latencia son importantes. La desventaja de utilizar un protocolo personalizado es que definir el protocolo lleva más tiempo que definir la API de JavaScript Websocket que admiten todos los principales navegadores.