Concepto Ajax, protocolo Http, solicitud Ajax y sus problemas comunes

Otro conocimiento de AJAX
Política del mismo origen de AJAX y soluciones de problemas entre dominios: haga clic aquí
Diferentes formas de enviar solicitudes de AJAX: haga clic aquí

concepto de ajax

El nombre completo de AJAX es Javascript y XML asíncronos, que es JS y XML asíncronos . AJAX puede enviar una solicitud asíncrona al servidor en el navegador, la mayor ventaja: obtener datos sin actualizar . AJAX no es un nuevo lenguaje de programación, sino una nueva forma de combinar los estándares existentes.

XML : lenguaje de marcado extensible . XML fue diseñado para transmitir y almacenar datos . XML es similar a HTML, la diferencia es que hay etiquetas predefinidas en HTML, pero no hay etiquetas predefinidas en XML, y todas ellas son etiquetas personalizadas, que se utilizan para representar algunos datos. (Actualmente reemplazado por JSON)

Ventajas y desventajas del Ajax

ventaja:

  • Es posible comunicarse con el lado del servidor sin actualizar la página.
  • Le permite actualizar partes del contenido de la página según los eventos del usuario.

defecto:

  • Sin historial de navegación, sin rebobinado.
  • Hay un problema de dominio cruzado (mismo origen).
  • SEO hostil (no se puede encontrar en el código fuente).

protocolo HTTP

El nombre completo de HTTP es protocolo de transporte de hipertexto ( Protocolo de transferencia de hipertexto ), que especifica las reglas para la comunicación mutua entre los navegadores y los servidores de la World Wide Web.

mensaje de solicitud

Línea de solicitud : POST /URL HTTP协议版本
encabezado de solicitud :

Host:值

Cookie: 值

Content-type:值

User-Agent:值Etc.
Línea vacía :
cuerpo de solicitud : si es un cuerpo de solicitud GET, está vacío, si es POST, puede que no esté vacío
Por favor agregue una descripción de la imagen

mensaje de respuesta

Línea de respuesta : HTTP协议版本 响应状态码 响应状态字符串
encabezados de respuesta :

Content-type:值

Content-length:值

Content-encoding:值
Etc. Línea vacía :
cuerpo de respuesta : contenido de sintaxis HTML
Por favor agregue una descripción de la imagen

Preparación del caso Ajax

Expresar uso básico

Primero descargue el nodo y configure el entorno del nodo, luego ingréselo en la terminal de vscode npm i express. Si hay un error, puede intentar ejecutar vscode con el administrador e intentar nuevamente. Si aún no funciona, busque la ubicación del carpeta del nodo y busque los node_cache node_global node_modulestres archivos por separado –> Propiedades –> Seguridad –> Cambiar permisos a control total.

Se puede instalar de forma global, es decir, en el directorio raíz de node.jsnpm i express -g

crear un servidor

Cree un nuevo archivo js en el directorio actual (no necesariamente en el directorio raíz de la instalación rápida) y luego ingrese el terminal --> directorio actual --> entrada para node 文件名iniciar el servicio

Por favor agregue una descripción de la imagen

  • Puede usar nodemon para guardar y reiniciar automáticamente

    Instalar nodemon:npm install -g nodemon

    Uso: Entrar en el directorio actual terminalnodemon 文件名

    De esta forma, no tendrá que reiniciar el servicio cada vez que realice un cambio.

    Nota: si se informa un error, ingrese npx nodemon 文件名e intente nuevamente

Enviar una solicitud AJAX

OBTENER solicitud

Haga clic en el botón para mostrar el cuerpo de la respuesta en el div: haga clic en el botón para enviar una solicitud AJAX al servidor y luego tome el cuerpo de la respuesta y colóquelo en el div.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #result {
      
      
        width: 200px;
        height: 100px;
        border: solid 1px pink;
      }
    </style>
  </head>
  <body>
    <button>点击发送请求</button>
    <div id="result"></div>

    <script>
      //获取button元素
      const btn = document.querySelector("button");
      const result = document.querySelector("#result");
      btn.addEventListener("click", function () {
      
      
        //1.创建对象
        const xhr = new XMLHttpRequest();
        //2.初始化,设置请求的方法和url
        xhr.open("GET", "http://127.0.0.1:8000/server?a=1&b=2&c=3");
        //3.发送
        xhr.send();

        //4.事件绑定,处理服务端返回的结果
        //on 当……的时候
        //readyState是xhr对象中的属性,表示状态0 1 2 3 4
        //其中0-未初始化 1-open调用完毕 2-send调用完毕 3-服务端返回了部分结果 4-服务端返回了所有结果
        //change 改变
        xhr.onreadystatechange = function () {
      
      
          //判断服务端是否返回了所有结果
          if (xhr.readyState === 4) {
      
      
            //判断响应状态码 200 404 403 401 500
            // 2xx ,2开头都表示成功
            if (xhr.status >= 200 && xhr.status < 300) {
      
      
              //如果响应成功处理结果 行 头 空行 体
              console.log("状态码:", xhr.status); //状态码
              console.log("状态字符串:", xhr.statusText); //状态字符串
              console.log("响应头:", xhr.getAllResponseHeaders()); //所有的响应头
              console.log("响应体:", xhr.response); //响应体

              //设置result文本
              result.innerHTML = xhr.response;
            }
          }
        };
      });
    </script>
  </body>
</html>

Establecer parámetros de URL: 用?隔开,=赋值,&分隔
por ejemplo:http://127.0.0.1:8000/server?a=1&b=2&c=3

Archivo servidor server.js:

//1、引入express
const express = require('express');

//2、创建应用对象
const app = express();

//3、创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server',(request,response)=>{
    
    
    //设置响应头 设置允许跨域
    response.setHeader('Access-Controll-Allow-Origin','*');
    //设置响应
    response.send('HELLO AJAX');
});

//4、监听端口启动服务
app.listen(8000,()=>{
    
    
    console.log("服务已经启动,8000端口监听中");
})

Solicitud POST

El mouse envía una solicitud AJAX a través del div y luego recupera el cuerpo de la respuesta y lo coloca en el div.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #result {
      
      
        width: 200px;
        height: 100px;
        border: solid 1px pink;
      }
    </style>
  </head>
  <body>
    <div id="result"></div>
    <script>
      const result = document.querySelector("#result");
      result.addEventListener("mouseover", function () {
      
      
        //1.创建对象
        const xhr = new XMLHttpRequest();
        //2.初始化 设置类型与url
        xhr.open("POST", "http://127.0.0.1:8000/server");
        //设置请求头:固定写法,第一个参数设置请求体内容类型,第二个参数是参数查询字符串的类型
        xhr.setRequestHeader(
          "Content-Type",
          "application/x-www-form-urlencoded"
        );
        //3.发送请求,在这里传参,任意类型都可以
        xhr.send("a=1&b=2&c=3");
        // xhr.send('a:1&b:2&c:3');
        // xhr.send('1232142412421312');
        //4.绑定事件
        xhr.onreadystatechange = function () {
      
      
          //判断服务端是否返回所有结果
          if (xhr.readyState === 4) {
      
      
            //判断响应是否成功
            if (xhr.status >= 200 && xhr.status < 300) {
      
      
              //处理服务端返回的结果
              result.innerHTML = xhr.response;
            }
          }
        };
      });
    </script>
  </body>
</html>

servidor.js:

//1、引入express
const express = require("express");

//2、创建应用对象
const app = express();

//3、创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
//GET请求
app.get("/server", (request, response) => {
    
    
  //设置响应头 设置允许跨域
  response.setHeader("Access-Controll-Allow-Origin", "*");
  //设置响应
  response.send("HELLO AJAX");
});

//POST请求
app.post("/server", (request, response) => {
    
    
  //设置响应头 设置允许跨域
  response.setHeader("Access-Controll-Allow-Origin", "*");
  //设置响应
  response.send("HELLO AJAX POST");
});

//4、监听端口启动服务
app.listen(8000, () => {
    
    
  console.log("服务已经启动,8000端口监听中");
});

Respuesta JSON

El cuerpo de la respuesta del servidor también se puede configurar como un dato para enviar, pero no se puede escribir directamente. Debe convertirse JSON.stringify(数据)en una cadena JSON.

//可以接收任意类型的请求
app.all("/json-server", (request, response) => {
    
    
  //设置响应头 设置允许跨域
  response.setHeader("Access-Control-Allow-Origin", "*");
  response.setHeader("Access-Control-Allow-Headers", "*");
  //响应一个数据
  const data = {
    
    
    name: "haha",
  };
  //对对象进行字符串转换
  let str = JSON.stringify(data);
  //设置响应体
  response.send(str);
});

Cuando la página obtiene el cuerpo de respuesta de la cadena JSON, no se puede reconocer, por lo que es necesario convertir la cadena JSON en un objeto js. Hay dos formas:

  • conversión manualJSON.parse(xhr.response)
  • conversión automáticaxhr.responseType = 'json';
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #result {
      
      
        width: 200px;
        height: 100px;
        border: solid 1px pink;
      }
    </style>
  </head>
  <body>
    <div id="result"></div>
    <script>
      const result = document.querySelector("#result");
      window.onkeydown = () => {
      
      
        const xhr = new XMLHttpRequest();
        //设置响应体数据类型
        xhr.responseType = "json";
        xhr.open("GET", "http://127.0.0.1:8000/json-server");
        xhr.send();
        xhr.onreadystatechange = function () {
      
      
          if (xhr.readyState === 4) {
      
      
            if (xhr.status >= 200 && xhr.status < 300) {
      
      
              //result.innerHTML = xhr.response;

              //手动对数据进行转换
              //let data = JSON.parse(xhr.response);
              //console.log(data);
              // result.innerHTML = data.name;

              //自动转换
              console.log(xhr.response);
              result.innerHTML = xhr.response.name;
            }
          }
        };
      };
    </script>
  </body>
</html>

Problemas con las solicitudes de Ajax

Problema de almacenamiento en caché de IE

//针对IE缓存
app.get("/ie", (request, response) => {
    
    
  //设置响应头 设置允许跨域
  response.setHeader("Access-Control-Allow-Origin", "*");
  //设置响应
  response.send("HELLO IEhhh");
});

Es decir, cuando cambie el cuerpo de su respuesta, no se actualizará, sino que se almacenará en caché. Para resolver este problema, la URL de cada solicitud debe ser diferente. Luego, pasaremos un parámetro más tarde, y el valor es una marca de tiempo (porque la marca de tiempo es imposible de repetir En este caso, el navegador pensará que la URL es diferente y reenviará la solicitud para resolver el problema), lo que puede resolver el problema de que el caché de IE no se actualiza cuando se cambia el cuerpo de la respuesta .

xhr.open("GET", "http://127.0.0.1:8000/ie?t=" + Date.now());

Tiempo de espera de solicitud de Ajax y manejo de excepciones de red

No podemos garantizar que el servidor pueda responder con prontitud y rapidez. En este momento, podemos establecer un tiempo de espera para Ajax y luego devolver un recordatorio al usuario. Cuando la red es anormal, también podemos devolver un recordatorio para mejorar la experiencia del usuario.

El servidor escribe un temporizador y envía el cuerpo de respuesta después de 2 segundos

//延时响应
app.get("/delay", (request, response) => {
    
    
  //设置响应头 设置允许跨域
  response.setHeader("Access-Control-Allow-Origin", "*");
  //设置响应
  //服务端写个定时器,2秒后发送响应体过去
  setTimeout(() => {
    
    
    response.send("HELLO 延时响应");
  }, 2000);
});

Luego, cuando hace clic en el botón para enviar la solicitud, puede configurar el tiempo de espera xhr.timeouty la devolución de llamada de tiempo de espera xhr.ontimeout, así como la devolución de llamada de excepción de redxhr.onerror

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>IE缓存问题</title>
    <style>
      #result {
      
      
        width: 200px;
        height: 100px;
        border: solid 1px pink;
      }
    </style>
  </head>
  <body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <script>
      const btn = document.querySelector("button");
      const result = document.querySelector("#result");
      btn.addEventListener("click", () => {
      
      
        const xhr = new XMLHttpRequest();
        //超时设置 2s
        xhr.timeout = 2000;
        //超时回调
        xhr.ontimeout = function () {
      
      
          alert("网络异常,请稍后重试!");
        };
        //网络异常回调
        xhr.onerror = function () {
      
      
          alert("你的网络似乎出了一些问题!请检查后重试!");
        };
        xhr.open("GET", "http://127.0.0.1:8000/delay");
        xhr.send();
        xhr.onreadystatechange = function () {
      
      
          if (xhr.readyState === 4) {
      
      
            if (xhr.status >= 200 && xhr.status < 300) {
      
      
              result.innerHTML = xhr.response;
            }
          }
        };
      });
    </script>
  </body>
</html>

Solicitud de cancelación manual de Ajax

Cuando no se ha respondido a la solicitud después de enviarla, la solicitud se puede cancelar manualmente y se puede devolver un recordatorio cuando se cancela.

Configure un temporizador para enviar el cuerpo de la respuesta:

app.get('/cancel', (request, response) => {
    
    
    //设置响应头
    response.setHeader('Access-Control-Allow-Origin', '*');
    //设置响应体
    setTimeout(() => {
    
    !
        response.send('HELLO 请求已经被取消');
    }, 2000);
})

Para cancelar una solicitud, utilice xhr.abort()el método abort=abort.
Aquí hay un problema de alcance. La solución es definir xhr fuera y dar un valor nulo, luego asignar la instancia de xhr y luego llamar al método. (La asignación repetida no puede ser constante)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>手动取消请求</title>
  </head>
  <body>
    <button>点击发送请求</button>
    <button>点击取消请求</button>
    <div id="result"></div>
    <script>
      const send = document.querySelectorAll("button")[0];
      const cancel = document.querySelectorAll("button")[1];

      let xhr = null;
      //发送请求
      send.onclick = function () {
      
      
        xhr = new XMLHttpRequest();
        xhr.open("GET", "http://127.0.0.1:8000/cancel");
        xhr.send();
      };
      //取消请求,abort方法
      cancel.addEventListener("click", function () {
      
      
        xhr.abort(); //先点send再点cancel不会报错,先点cancel报错
      });
    </script>
  </body>
</html>

Problema de solicitud de envío repetido de Ajax

Cuando el usuario hace clic frenéticamente en un botón, el navegador enviará la misma solicitud repetidamente, lo que provocará una presión excesiva en el servidor. Solución: cuando el usuario envía una solicitud, primero verifique si existe la misma solicitud anterior, si la hay, cancele la solicitud anterior y solo responda a la última solicitud (aquí está la idea de anti-vibración, revise el anti -agitar el estrangulamiento haga clic aquí lugar )

<script>
      const btn = document.querySelector("button");
      let xhr = null;
      //标识变量 是否正在发送请求
      let isSending = false;
      //发送请求
      btn.onclick = function () {
    
    
        //判断标识变量
        if (isSending) x.abort();
        xhr = new XMLHttpRequest();
        //修改标识变量的值
        isSending = true;
        xhr.open("GET", "http://127.0.0.1:8000/delay");
        xhr.send();
        xhr.onreadystatechange = function () {
    
    
          if (xhr.readyState === 4) {
    
    
            isSending = false;
          }
        };
      };
</script>

Supongo que te gusta

Origin blog.csdn.net/weixin_56498069/article/details/132170393
Recomendado
Clasificación