Un frente y la interacción cara posterior (Ajax objetos FormData y subir archivos)

1. Puntos clave agarran y el conocimiento

## llave maestra

  1. Explicación del uso del ajax básica
  2. Vamos a utilizar el XMLHttpRequest intercambio de datos implementa el objeto
  3. Aprender onreadystatechange información de respuesta del servidor (código de estado)
  4. Los objetos se pueden utilizar para cargar archivos FormData
  5. Aprender de subida objeto de evento (el objeto evento bajo XMLHttpRequest)

## puntos de conocimiento

  1. el uso de AJAX
  2. objeto XMLHttpRequest
  3. objetos FormData
  4. objeto de evento de carga

2. Registro de revisión breve

1, propuesto ajax verificar las necesidades de nombre de usuario;

2, después de errores de validación, si se resuelven por saltar un montón de problemas;
 

3. Uso de Ajax para resolver el problema de la verificación del nombre de usuario

- Ajax es: Ajax es decir, "Asynchronous JavaScript y XML" (JavaScript asíncrono y XML)

- Ajax uso básico:

  • Nuevo objeto XMLHttpRequest;
 let xhr = new XMLHttpRequest();
  • solicitud de configuración de parámetros
 xhr.open("get","/checkUser",true); //true是异步,false是同步
  • Recepción de un valor de retorno
  xhr.onload = function(){
     let res = JSON.parse(xhr.responseText);
  }
  • El envío de una solicitud del servidor
xhr.send();

Caso se logra mediante ajax asíncrono sin verificación de actualización Nombre de usuario:

 login.css:

.loginContainer{
    margin: 0 auto;
    width: 600px;
    text-align: center;
    padding-top: 20px;
    padding-bottom: 50px;
    border: 1px solid;
}
.loginContainer input{
    margin-bottom: 20px;
}
.loginStyle{
    width: 160px;
    height: 40px;
    background: rgb(50,203,77);
    color: white;
    font-size: 17px;
}
.inputStyle{
    width: 200px;
    height: 30px;
    padding: 5px;
    outline: none;
}

.inputStyle:focus{
    border: 1px solid rgb(50,203,77);
}
form{
    position: relative;
}
.exchange{
    position: absolute;
    top:8px;
    right: 65px;
    color: red;
    display: none;
}

user.json:

[
    {
        "id":1,
        "username":"zhangsan",
        "pwd":"123"
    },{
        "id":2,
        "username":"lisi",
        "pwd":"123"
    }
]

 login.js:

const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");
// const views = require("koa-views");
const userData = require("./data/user.json");

let app = new Koa();
let router = new Router();

app.use(static(__dirname + "/static"));
//前面页面直接放到static里时,只能通过login.html访问,不能通过/直接访问
router.get("/checkUser", (cxt, next) => {
    let username = userData.find(item=>item.username === cxt.query.username);
    console.log(username);
    if(username){
        cxt.body = {
            status:1,
            msg:"用户名正确"
        };
    }else{
        cxt.body = {
            status:0,
            msg:"用户名错误"
        };
    }
});

app.use(router.routes());
app.listen("9090");

login.html:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <link rel="stylesheet" href="css/login.css" />
  <title>Document</title>
</head>

<body>
  <div class="loginContainer">
    <h1>登录</h1>
    <form action="/checkUser" method="post">姓名:
      <input class="inputStyle" type="text" name="username" />
      <div class="exchange">用户名错误</div>
      <br />密码:
      <input class="inputStyle" type="password" name="pwd" /><br />
      <input class="loginStyle" type="submit" value="登录" />
    </form>
  </div>
  <script>
{
  //鼠标失去焦点时,进行无刷新验证
  let username = document.querySelectorAll("input");
  let exchange = document.querySelector(".exchange");
  username[0].onblur = function(){
    let xhr = new XMLHttpRequest();
    xhr.open("get","/checkUser?username="+this.value,true);//true表示异步发送请求,false同步发送请求
    xhr.onload = function() {
      //注意返回数据是从XMLHttpRequest对象中获得的
      let res = JSON.parse(xhr.responseText);
      // console.log(JSON.parse(xhr.responseText).msg);
      // console.log(xhr.response);
      exchange.style.display = "block";
      exchange.innerHTML = JSON.parse(xhr.responseText).msg;
      console.log(res.status);
      
      if(res.status === 1){
        //获取到的数据是JSON格式的,需要将其转为对象
        exchange.style.color = "green";
      }else{
        exchange.style.color = "red";
      }
    }
    xhr.send();
  }
}
  </script>
</body>

4. Para una explicación detallada de ajax

Precauciones 4.1get

  - Obtener el paso de parámetros por parmas

  - Lee y queryString problemas a través de la participación masiva url

conseguir el traspaso de parámetros de dos maneras:

  1. queryString, participación masiva de queryString tienen restricciones de longitud, el valor predeterminado es 2048
  2. / Get / Identificación

Tenga en cuenta el punto de paso de paso de parámetros:

  • querystring paso de parámetros y obtener / modo de solicitud post es los dos conceptos, en lugar de utilizar el paso de parámetros se querystring solicitud GET, parámetros POST también pueden transmitirse a través de la cadena de consulta;
  • Cuando la cadena de consulta de parámetros que pasa a través de la dirección de recepción de fondo no se ve afectada, pero, si se utiliza el get / Identificación del fondo de transmisión / modo de referencia obligada / get /: id parámetros de recepción y el modo, el valor del parámetro se obtiene por ctx.params;

queryString parámetro de modo de pasar: el ejemplo anterior

'/ Solicitud de dirección / parámetro' parámetro de modo que pasa: usando '/ Dirección Solicitud /: el parámetro' recibe la dirección, valores de los parámetros adquiridos utilizando ctx.params

<body>
    <button>点击发送get请求</button>
    <script>
        {
            //通过/get/3的方式进行传参,后台通过/get/:id进行获取,ctx.params得到具体参数值
            document.querySelector("button").onclick = function(){
                let xhr = new XMLHttpRequest();
                xhr.open("get","/getInfo/1");
                xhr.onload = function(){
                    console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
                }
                xhr.send();
            };
        }
    </script>
</body>

login.js:

//get请求
router.get("getInfo","/getInfo/:id",ctx=>{
    console.log(ctx.params);//{ id: '1' }
    ctx.body = {
        status:1,
        msg:"请求成功"
    };
});

Precauciones 4.2post

publicar generalmente no participación de las masas por queryString, porque la longitud limitada participación de las masas queryString (servidores límite), el valor predeterminado 2048.

paso de post parámetro de referencia se hace pasar a través del cuerpo HTTP, el cuerpo debe ser ajustado a pasar parámetro formato de codificación . Forma con la forma de codificación por defecto de formato <acción de formulario = "" enctype = "application / x-www-form-urlencoded"> </ form>. formulario de forma puede ser omitido, pero no se puede omitir cuando ajax petición.

notas:

  1. Cuando se transmiten datos para ajustar el formato de texto de encabezado HTTP;
  2. Obtener información del encabezado: getAllResponseHeaders o getResponseHeader;

- datos de texto de envío cuando es necesario configurar formato de cabecera http:

xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");  //默认编码
xhr.setRequestHeader("Content-type","multipart/form-data");  //二进制编码,上传文件时使用
xhr.setRequestHeader("Content-type","application/json");  //json编码:传输数据也需要时JSON格式

Ejemplo: Nota que el uso de solicitud POST, el módulo de fondo koa-cuerpo debe ser utilizado con el fin de obtener los parámetros

<body>
    <button>点击发送post请求</button>
    <script>
        {
            //通过/get/3的方式进行传参,后台通过/get/:id进行获取,ctx.params得到具体参数值
            document.querySelector("button").onclick = function(){
                let xhr = new XMLHttpRequest();
                xhr.open("post","/getPostInfo");
                xhr.onload = function(){
                    console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
                }
                //设置正文请求头
                xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
                let data = "username=zs&age=20";
                xhr.send(data);
            };
        }
    </script>
</body>
const koaBody = require("koa-body");
app.use(koaBody());
//post请求
router.post("/getPostInfo",ctx=>{
    console.log(ctx.request.body);//{ username: 'zs', age: '20' }
    
    ctx.body = {
        status:1,
        msg:"请求成功"
    };
});

Cuando la cabecera HTTP de texto con formato JSON como: también se requiere formato de transmisión de datos JSON, se debe utilizar el JSON.stringify () formato a los datos en JSON

 //正文请求头设置为json时,传输数据也需要是JSON格式
                xhr.setRequestHeader("content-type","application/json; charset=utf-8");
                let data = JSON.stringify({
                    username:'zs',
                    age:12
                });

  - Obtener la información del encabezado: getAllResponseHeaders () obtiene toda la información del encabezado o getResponseHeader ( "atributos encabezado de la solicitud") que se necesita una información de cabecera

                xhr.onload = function(){
                    console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
                    //获取所有头部信息
                    console.log(xhr.getAllResponseHeaders());
                    //获取某个头部信息
                    console.log(xhr.getResponseHeader("content-type"));//application/json; charset=utf-8
                }

Resultados: la información de cabecera Todo

fecha: Mir 18 Sep 2,019 mil 01:59:50 GMT
conexión: keep-alive
Content-Length: 33
Content-Type: application / json; charset = utf-8

4.3 ajax síncrona y asíncrona

  • Asíncrono solicita u otras peticiones no afecta a la aplicación del código;
  • Al configurar la ejecución sincrónica, al igual que otras solicitudes o código que pueden ser ejecutadas después de la solicitud, se llevará a cabo

Asíncrono: orden de ajuste asíncrona no afecta a la ejecución de código u otras solicitudes

<body>
    <button>按钮一</button>
    <button>按钮二</button>
    <script>
    {
        let btns = document.querySelectorAll("button");
        btns[0].onclick = function(){
            let xhr = new XMLHttpRequest();
            xhr.open("get","/getInfo/2",true);
            xhr.onload = function(){
                console.log(xhr.responseText);
            }
            xhr.send();
        }
        //点击第二个按钮时进行打印
        btns[1].onclick = function(){
            console.log("按钮二打印。。。");
            
        }
    }
    </script>
</body>

Resultado: El botón para imprimir una solicitud no afecta a los resultados de dos botones

 

Asíncrono: Al configurar la ejecución sincrónica, al igual que otras solicitudes o código que pueden ser ejecutadas después de la solicitud, se llevará a cabo

 xhr.open("get","/getInfo/2",false);

 resultados:

 

5.onreadystatechange

5.1 onreadystatechange

onreadystatechange: hay función de procesamiento de respuesta del servidor cada vez que cambia readyState, la función onreadystatechange será ejecutado.

5.2 readyState

readyState: información de respuesta de servidor de estado allí.

  • 0: La petición no se ha inicializado (método se crea proxy, pero todavía no llama abierta ())
  • 1: Se establece la conexión del servidor ( `método open` se ha llamado)
  • 2: solicitud ha sido recibida ( `método send` se ha llamado, y el estado y la cabeza ya está disponible)
  • 3: Proceso de la solicitud (descargar, `propiedad responseText` ya contiene datos parciales)
  • 4: solicitud se ha completado, y la respuesta está listo (operación de descarga se ha completado)

códigos de estado comunes 5.3 de estado

Estado de estado común --http Código de estado
código de estado HTTP descripción

100

Continuar. La parte restante sigue respondiendo, presentar una solicitud

200

éxito

301

movimiento permanente. Solicitar recursos de forma permanente a una nueva ubicación

302

medida temporal. petición de recursos de cero a una nueva ubicación

304

Sin modificar. Que la última petición del recurso no se modifica, la respuesta no contiene el contenido del recurso

401

Autorizado requiere autenticación

403

Prohibido. Solicitud es denegada

404

No lo encuentra, el servidor no necesita encontrar recursos

500

Error interno del servidor. El servidor encontró un error y no puede cumplir con la solicitud

503

Servidor no está disponible. servicio temporal sobrecargada y no puede procesar la solicitud

Ejemplo: 

<body>
    <button>点击</button>
    <script>
        document.querySelector("button").onclick = function(){
            let xhr = new XMLHttpRequest();
            xhr.open("get","/getInfo/3",true);
            xhr.onreadystatechange = function(){
                //判断服务求响应状态为4和返还状态200(成功)
                if(xhr.readyState == 4){
                    if(xhr.status == 200){
                        console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
                    }
                }
            }
            xhr.send();
        };
    </script>
</body>

 De hecho, no están utilizando onload información de respuesta del servidor y devuelve un código de estado: proceso de carga será más concisa recomienda

xhr.onload = function(){
                console.log(xhr.readyState);//4
                console.log(xhr.status);//200
                console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
            }

tipo de datos 5.4 regreso  

  • El servidor ha devuelto datos JSON: xhr.responseText para obtener
xhr.responseText  //来获取
  • datos XML devueltos servidor:
  1. xhr.responseXML // obtener el valor
  2. servidor de respuesta proporcionado en el ctx.set contenido de tipo de contenido ( "tipo de contenido", "text / html");
  3. Reescribiendo XML distal (caso Tipo volver tipo de contenido no se especifica): xhr.overrideMimeType ( 'text / xml; charset = UTF-8'); Tenga en cuenta que la propiedad puede haber ningún espacio entre el
xhr.responseXML //获取值

 Ejemplo:

HTML front-end:

<body>
    <button>点击获取XML数据</button>
    <script>
    {
        document.querySelector("button").onclick = function(){
            let xhr = new XMLHttpRequest();
            xhr.open("get","/getXMLInfo",true);
            //如果后台没有设置XML的content-type,前端就必须重写格式
            xhr.overrideMimeType('text/xml;charset=utf-8');
            xhr.onload = function(){
                //获取XML格式数据
                console.log(xhr.responseXML);
                console.log(xhr.responseXML.getElementsByTagName("name")[0]);
                //获取原始数据
                console.log(xhr.response);
                
            }
            xhr.send();
        }
    }
    </script>
</body>

antecedentes:

//获取XML数据
router.get("/getXMLInfo",ctx=>{
    ctx.set("content-type","text/xml");
    //注意这里反引号和xml内容不能换行
    ctx.body = `<?xml version='1.0' encoding='utf-8' ?>
        <books>
            <nodejs>
                <name>nodeJS实战</name>
                <price>52.0元</price>
            </nodejs>
            <react>
                <name>react进阶</name>
                <price>56.0元</price>
            </react>
        </books>`;
});

 resultados:

Para evitar que el fondo no escribió el contenido de tipo XML, necesidad de reescribir formato XML en la parte delantera:

xhr.overrideMimeType('text/xml;charset=utf-8');

6. Uso FormData para subir archivos

6.1 Creación de objetos FormData

notas:

  1. <Input type = clase "archivo" = "miarchivo"> ​​adquirida por la matriz es la clase de atributos de archivos;
  2. Crear un archivo subido objetos a través de nuevos FormData ();
  3.  formData.append (nombre, valor); nombre nombre debe ser consistente con el fondo cuando se recibe, el valor puede ser un archivo de datos normales
  4. carga de archivos debe ser transmitida a través del texto, es necesario el uso de la solicitud posterior; Content-Type se ajusta automáticamente el uso FormData, que no es necesario ajustar manualmente
  5. Al recibir los datos de fondo, atributo de nombre () se puede obtener en los datos correspondientes o archivos distal append
  6. A continuación, los archivos de volcado fs correspondientes al módulo. Ese fichero de camino ctx.request.files.img.path temporal, volcado por el camino hacia el archivo del servidor a una ruta temporal
  7. Es posibles problemas con los permisos de la carpeta, es necesario abrir manualmente los permisos de archivo de volcado. Y la carpeta no existe, crear una carpeta

Ejemplo:

frente:

<body>
    <input type="file" class="myfile">
    <button>点击上传</button>
    <script>
        document.querySelector("button").onclick = function(){
            let myfile = document.querySelector(".myfile");
            //files属性返回的是类数组
            let files = myfile.files;
            //创建FormData对象,进行上传
            let formData = new FormData();
            //img表示name,相当于form表单中的name属性,file[0]表示要上传的单个文件
            formData.append("img",files[0]);
            //其他的数据,也可以进行传输
            formData.append("username","张三");

            //文件上传必须通过正文方式进行传递,所以必须使用post请求
            //使用FormData时会自动对content-type进行设置,就不需要再进行手动设置
            let xhr = new XMLHttpRequest();
            xhr.open("post","/upload",true);
            xhr.onload = function(){
                console.log(xhr.responseText);
            };
            xhr.send(formData);
        };
    </script>
</body>

antecedentes:

const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");
const koaBody = require("koa-body");
const fs = require("fs");

let app = new Koa();
let router = new Router();
app.use(static(__dirname + "/static"));
//上传文件时,必须设置允许文件上传,否则接收不了
app.use(koaBody({
    multipart:true
}));

//上传文件
router.post("/upload",ctx=>{
    //通过前端append()中的name属性即可获取到对应数据或文件
    // console.log(ctx.request.body);//{ username: '张三' }
    // console.log(ctx.request.files.img);
    //通过fs模块对相应文件进行转存即可
    //ctx.request.files.img.path即文件的临时路径,对临时路径中的文件转存到服务器下路径即可
    let fileData = fs.readFileSync(ctx.request.files.img.path);
    //文件转存时有可能出现文件夹权限问题,需要手动开启权限
    //判断文件夹不存在,需要先创建文件夹
    if(!fs.existsSync("static/imgs")){
        fs.mkdirSync("static/imgs/");
    }
    fs.writeFileSync("static/imgs/"+ctx.request.files.img.name,fileData);
    
    ctx.body = {
        status:1,
        msg:"文件上传成功"
    };
});

app.use(router.routes());
app.listen("8888");

 Los resultados: { "status": 1, "msg": "El archivo subido correctamente"}

6.2 supervisar el evento de carga progreso --upload

Los siguientes eventos están bajo los eventos de carga:

  • onLoadStart empezar de subida
  • transferencia de datos onProgress en (evt.total: tamaño total que va a transmitirse; evt.loaded: la posibilidad de subir el tamaño del archivo actual;)
  • onabort operación de carga de rescindir (cancelar xhr.abort carga ())
  • No se pudo subir onerror
  • onload cargado correctamente
  • onloadend carga esté completa (con o sin éxito)

  De carga de archivos de seguimiento de progreso ejemplos:

notas:

  • Monitorear la velocidad de subida de archivos (requiere onLoadStart y onProgress diferencia de tiempo y el tamaño del archivo subido archivo diferencia de tiempo), el tamaño del archivo actual / diferencia de tiempo, la velocidad de subida de documentos;
  • Las unidades de procesamiento necesitan para cargar b / s kb / s;

Archivo de página de carga:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    .progressSpan{
        display: none;
        color: seagreen;
    }

    </style>
</head>
<body>
    <input type="file" class="myfile">
    进度:<progress value="0" max="100"></progress>&nbsp;&nbsp;<span class="progressSpan">10%</span>&nbsp;&nbsp;
    速度:<span class="speed">20b/s</span><br><br>
    <button>点击上传</button>
    <button>取消上传</button>
    <script>
    {
        let btns = document.querySelectorAll("button");
        let xhr = new XMLHttpRequest();
        btns[0].onclick = function(){
            let sTime = 0;//文件开始上传时间
            let eTime = 0;//文件开始上传时间
            let fileInitSize = 0;//文件开始上传大小
            xhr.open("post","/fileUpload",true);
            //获取上传文件
            let file = document.querySelector(".myfile").files[0];
            let formData = new FormData();
            formData.append("imgFile",file);

            //upload事件监控文件上传进度
            xhr.upload.onloadstart = function(){
                console.log("文件开始上传");
                sTime = new Date().getTime();
                fileInitSize = 0;
            };
            xhr.upload.onprogress = function(evt){
                console.log("文件上传中");
                //在onprogress事件中监控上传进度
                let progress = (evt.loaded / evt.total * 100).toFixed(0);
                //将进度进行显示
                document.querySelector("progress").value = progress;
                document.querySelector(".progressSpan").style.display = "inline-block";
                document.querySelector(".progressSpan").innerHTML = progress+"%";

                //监控文件上传速度(需要onloadstart和onprogress的时间差,及时间差内文件已上传的文件大小)
                eTime = new Date().getTime();
                //需要将时间差转为秒s
                let diffTime = (eTime-sTime)/1000;
                //各个进度文件上传的文件大小
                let curFileSize = evt.loaded;
                let diffFileSize = curFileSize - fileInitSize;
                //获取上传速度(需要处理上传的单位b/s kb/s)
                let speed = diffFileSize/diffTime;
                let unit = "";
                if(speed/1024>1){
                    speed = speed/1024;
                    unit = "b/s";
                }
                if(speed/1024>1){
                    speed = speed/1024;
                    unit = "kb/s";
                }
                document.querySelector(".speed").innerHTML = speed.toFixed(2)+unit;
                //使用当前文件大小/时间差 即文件上传速度
                sTime = eTime;
                fileInitSize = curFileSize
            };
            xhr.upload.onabort = function(){
                console.log("取消文件上传");
            };
            xhr.upload.onerror = function(){
                console.log("文件上传失败");
            };
            xhr.upload.onload = function(){
                console.log(xhr.responseText);
            };
            xhr.upload.onloadend = function(){
                console.log("文件上传完成");
            };
            xhr.send(formData);
        };
        btns[1].onclick = function(){
            //取消文件上传方法
            xhr.abort();
        };
    }
    </script>
</body>
</html>

Proceso de fondo:

//监控文件上传进度
router.post("/fileUpload",(ctx,next)=>{
    //通过前端append()中的name属性即可获取到对应数据或文件
    //ctx.request.files.imgFile.path即文件的临时路径,对临时路径中的文件转存到服务器下路径即可
    let fileData = fs.readFileSync(ctx.request.files.imgFile.path);
    
    //判断文件夹不存在,需要先创建文件夹
    if(!fs.existsSync("static/imgs")){
        fs.mkdirSync("static/imgs/");
    }
    fs.writeFileSync("static/imgs/"+ctx.request.files.imgFile.name,fileData);
    
    ctx.body = {
        status:1,
        msg:"文件上传成功"
    };
});

 resultados:

7. Recuerda

1.ajax uso básico: crear el objeto XMLHttpRequest, xhr.open (), xhr.onload, xhr.send ()

2.Get / post en uso en ajax

3.ajax el retorno exitoso: onload

4. El formato de datos devuelto: respuesta, responseText, responseXML

5.FormData objetos: Crear objetos FormData, form.append (nombre, valor)

Método de seguimiento de eventos para cada carga de archivos: 6.upload objeto de evento

Publicado 95 artículos originales · ganado elogios 115 · vistas 120 000 +

Supongo que te gusta

Origin blog.csdn.net/qq_34569497/article/details/100917080
Recomendado
Clasificación