2022.09.01

学习资料:https://www.bilibili.com/video/BV1WC4y1b78y

express相关

    express是一个基于node.js的web应用框架,感觉上约等于flask或者tomcat之类的东西。

express的基础使用:

    在安装好express后,在每个js文件使用express之前先引入express并创建对象实例。

app.get(路径,回调函数):

    创建一个使用get方式请求的路由,当访问 /路径 时,将会发送get请求并且调用回调函数,回调函数的参数是请求报文和响应报文(可以有第三个参数next)
    此外还有post、all等接收其他请求方式的函数。
app.listen(端口,回调函数):
监听指定端口,访问服务时需要访问host+port,默认host是127.0.0.1

https://www.runoob.com/nodejs/nodejs-express-framework.html

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

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

//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get("/",function(request,response){
    //设置响应头,设置允许跨域
    response.setHeader("Access-Control-Allow-Origin","*");
    //设置响应
    response.send("hello express");
});

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

设置响应头以按规则允许请求头中的自定义键:

//设置响应头,设置允许自定义请求头键
response.setHeader("Access-Control-Allow-Headers","*");

其中 * 指任意匹配(似乎不是正则表达式,而是指定具体的请求头中key名)
以JSON字符串的形式返回一个对象:

app.all("/json-server",function(request,response){
    //准备一个对象以返回
    var data={
        name:"shinya",
        age:"15"
    }
    //使用JSON.stringify(obj)方法来将对象转换为字符串
    let str=JSON.stringify(data);
    //设置响应
    response.send(str);
});

延迟响应:
使用setTimeout(function, delayTime)来设置响应延时。

app.get("/delay",(req,resp)=>{
    resp.setHeader("Access-Control-Allow-Origin","*");
    //第一个参数是执行的方法,第二个是延时(ms)
    setTimeout(function(){
        resp.send("延时响应");
    },3000);
})

Ajax

发出请求

    在原生AJAX中,进行一次请求分为4步:创建XMLHttpRequest对象xhr,调用open方法指定请求方式和请求路径,发送请求,处理响应结果。

let btn=document.getElementById("btn");
//按钮点击事件
btn.onclick=function(){
    //1.创建对象
    const xhr=new XMLHttpRequest();
    //2.初始化  设置请求方法和url
    xhr.open("GET","http://127.0.0.1:8000/server");
    //xhr.open("GET","http://www.baidu.com");
    //报错,百度没有允许跨域。
    //3.发送
    xhr.send();
    //4.事件绑定  处理服务端返回的结果
    //onreadystatechange会在readystate改变时调用回调函数
    // 0 - 未初始化
    // 1 - open方法调用完毕
    // 2 - send方法调用完毕
    // 3 - 服务端返回了部分结果
    // 4 - 服务端返回了所有结果
    xhr.onreadystatechange=function(){
        if(xhr.readyState===4){
            if(xhr.status>=200 &&xhr.status<300){
                console.log(xhr.status);//状态码
                console.log(xhr.statusText);//状态字符串
                console.log(xhr.getAllResponseHeaders());//所有响应头
                console.log(xhr.response);//响应体

                //将结果展示在div内
                let textArea=document.getElementById("textArea");
                textArea.innerText=xhr.response;
            }
        }
    }
}

&nbsp;&nbsp;&nbsp;&nbsp;*注意:在GET方式中,参数必须在url中传递,不能在xhr.send()方法中传递,而POST方式下,参数必须在xhr.send()方法中传递,不能在url中显示传递,如下所示:

xhr.send("test from send() POST");

&nbsp;&nbsp;&nbsp;&nbsp;此外,一般而言约定俗成的传参格式有两种,第一种是形如”a=100&b=200”,另一种是Json

设置请求头(POST)

&nbsp;&nbsp;&nbsp;&nbsp;在请求发出(send)之前调用xhr.setHeader(key,value)方法以设置请求头

//设置请求头
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.setRequestHeader("name","Shinya");

&nbsp;&nbsp;&nbsp;&nbsp;*注意:如果使用了自定义而非预定义的请求头,则浏览器在发出此请求时会同时发出一个OPTION请求以确认服务器是否允许接收此请求头,如果不能则会报错。

解析不同类型的响应体数据

&nbsp;&nbsp;&nbsp;&nbsp;此处以JSON为例,在得到响应的JSON串之后,有手动转换和自动转换两种方式:
&nbsp;&nbsp;&nbsp;&nbsp;1.手动转换:使用JSON.parse()方法

//1.手动数据转换
//传输过来的xhr.response是一个字符串,所以使用JSON.parse()转换为JSON对象
let data=JSON.parse(xhr.response);
console.log(data);

&nbsp;&nbsp;&nbsp;&nbsp;2.自动转换:设置响应体数据类型

//在发送请求(send)之前设置响应体数据类型,则会按照此数据类型接收数据
xhr.responseType="json";
//2.自动数据转换,无需再调用parse方法,得到的xhr.response本身就是一个JSON对象
let data=xhr.response;
console.log(data)

超时/网络错误处理

&nbsp;&nbsp;&nbsp;&nbsp;1.超时处理,在响应超过预设时间时,调用xhr.ontimeout定义的回调函数,猜测xhr.ontimeout初始为空函数。
&nbsp;&nbsp;&nbsp;&nbsp;*注意:超时后,请求会自动被取消

//设置超时时间(ms)
xhr.timeout=2000;
//超时回调函数
xhr.ontimeout=function(){
    alert("响应超时,请检查网络!");
}

&nbsp;&nbsp;&nbsp;&nbsp;2.网络错误处理,在发现网络出错时调用xhr.onerror定义的回调函数

//网络错误回调
xhr.onerror=function(){
    alert("网络错误!");
}

&nbsp;&nbsp;&nbsp;&nbsp;手动取消请求:

xhr.abort()

&nbsp;&nbsp;&nbsp;&nbsp;防止多次重复请求:
&nbsp;&nbsp;&nbsp;&nbsp;设置一个flag,isSending,使其在xhr.send()之后为true,在xhr.readyState===4后变为false,并且在发出请求的按钮按下之后

使用jQuery发送请求:

&nbsp;&nbsp;&nbsp;&nbsp;jQuery.get()方法:
&nbsp;&nbsp;&nbsp;&nbsp;以get方式发送一个请求,接收1-4个参数,依次为url、数据、回调函数、接收数据类型,其中回调函数自带3个可选参数,data(响应体)、status(响应状态)、xhr(xhr对象)
&nbsp;&nbsp;&nbsp;&nbsp;https://www.runoob.com/jquery/ajax-get.html

jQuery.get("http://127.0.0.1:8000/jQuery-server",data,function(data){
    //此函数接收的参数data是响应体
    console.log(data);
},"json")

&nbsp;&nbsp;&nbsp;&nbsp;post() 方法与之类似。

&nbsp;&nbsp;&nbsp;&nbsp;jQuery.ajax()方法:
&nbsp;&nbsp;&nbsp;&nbsp;发送ajax请求,请求类型、请求地址等都可以设置,非常灵活。
&nbsp;&nbsp;&nbsp;&nbsp;https://jquery.cuishifeng.cn/jQuery.Ajax.html

$("button").eq(2).click(function(){
    //ajax方法接收的是一个对象,由花括号包裹
    $.ajax({
        url:"http://127.0.0.1:8000/jQuery-server",
        //请求中携带的数据
        data:{
            name:"shinya",
            age:15
        },
        type:"GET",
        dataType:"json",
        //成功时的回调
        success:function(data){
            console.log(data)
        },
        timeout:2000,
        //出错时的回调
        error:function(){
            alert("出错!")
        },
        //请求头
        headers:{
            head:"any"
        }
    })
})

JSONP:一种跨域请求方案

&nbsp;&nbsp;&nbsp;&nbsp;html中,img、iframe、script等标签自带跨域访问能力(如script中指定src以获取并执行一段js代码),jsonp就是利用了script标签的这种能力来实现跨域访问。
&nbsp;&nbsp;&nbsp;&nbsp;*即:不通过get()等方法来手动发请求,而是借助script标签来访问外部链接的资源,获取到的资源将会按照js的语法进行解析和执行。
&nbsp;&nbsp;&nbsp;&nbsp;*注意,使用此方法只能够发送GET请求。
&nbsp;&nbsp;&nbsp;&nbsp;应用:使用jsonp请求一段JSON代码并解析执行
&nbsp;&nbsp;&nbsp;&nbsp;服务端:

app.all("/check-username",function(req,resp){
    let data={
        exist:1,
        msg:"用户名已经存在"
    };
    let str=JSON.stringify(data);
    //使用反单引号``包裹的字符串可以使用${变量名}来完成字符串的注入拼接,这是ES6新特性
    resp.send(`handle(${str})`)
})

&nbsp;&nbsp;&nbsp;&nbsp;客户端:

<script>
    hint=document.getElementById("hint");
    input=document.getElementById("username");
    
    //data应为一个对象
    function handle(data){
        input.style.border="solid 2px red";
        hint.innerText=data.msg
    }
    
    input.onblur=function(){
        let username=this.value;
        //向服务端发出请求,检测用户名是否存在
        //1.创建script标签
        let scri=document.createElement("script");
        //2.设置标签的src属性
        scri.src="http://127.0.0.1:8000/check-username";
        //3.将标签插入到body中
        document.body.appendChild(scri)
    }
</script>

&nbsp;&nbsp;&nbsp;&nbsp;此处,向body中插入了新建的标签script,标签被新建后将会获取其src属性中的资源,访问/check-username路径之后,得到了服务端在resp.send()中发送的内容:“handle(${str})”,此后将其执行,即是执行了客户端所定义的handle方法。