学习记录4-Ajax,Promise,Axios

177 阅读5分钟

2022年5月26日 ,,,断断续续第三次看Ajax的课了

希望这次能学的差不多

优点

  • 无需刷新页面与服务器端进行通信
  • 允许根据用户事件来更新部分页面内容,就是可以在事件处理程序当中发请求

缺点

  • 没有浏览历史,不能回退
  • 存在跨域问题
  • SEU(搜索引擎优化)不太友好

一般http请求与ajax请求

  1. ajax请求时一种特别的http请求
  2. 对服务器端来说,没有区别,区别在浏览器端
  3. 浏览器端发送请求:只有XHR或fetch发出的才是ajax请求
  4. 服务端接收到响应 一般请求:浏览器一般会直接显示响应体数据,就是自动刷新,跳转页面 ajax 请求浏览器不会界面进行任何更新操作,只是调用监视的回调函数并传入响应相关数据

HTTP(hypertext transport protocol)

超文本传输协议,规定了浏览器和万维网服务器之间互相通信的规则

请求报文

  1. 行 请求类型 url路径 版本号
  2. 头 Host:baidu.com Coolie: name=jia
  3. 空行

响应报文

  • 行: 协议版本 相应状态码

  • 头: Content-Type: text/html;charset=utf-8

  • 空行

  • 体: 传回来的<html 一个小盒子接受传回来的文本'

 <style>
        #result{
            width: 200px;
            height: 100px;
            border:solid 1px #90b
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>

    <script>
        // 获取button元素
        const btn = document.getElementsByTagName('button')[0];
        // 获取result div
        const result = document.getElementById('result')
        // 绑定事件
        btn.onclick = function(){
            // 1. 创建对象
            const xhr =  new XMLHttpRequest
            // 2. 初始化 设置请求方法和 url
            xhr.open('GET', 'http://127.0.0.1:8000/server')
            // 3. 发送
            xhr.send();
            // 4. 事件绑定 处理服务端返回的结果

            // on 有when的意思 当...时候
            // readystate 是 xhr 对象中的属性,表示状态有五个值 0未初始化 1open方法调用完毕 
            // 2send方法调用完毕 3表示服务端返回部分结果 4服务端返回了所有结果
            xhr.onreadystatechange = function(){
                // 判断 (服务端返回了所有的结果)
                if(xhr.readyState === 4){
                    // 判断响应的状态码 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>

express做的简单后台

// 1.引入express
const { response } = require('express');
const { request } = require('express');
const express = require('express');

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

// 3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request, response)=>{
    // 设置响应头,Access-Control-Origin是名子,*是值 作用是允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    

    // 设置响应
    response.send('HELLO AJAX')
});

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

ajax设置url传参
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200')
post和这个差不多,请求参数要写在send里面

今天偷懒了,,,就学了一点点,,,希望明天能多学一点...

5月27日早八 继续 计划学完ajax promise axios

AJAX设置请求头信息

 // 在初始化请求下面直接写就行
 // 设置请求头
            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

服务端响应JSON数据

 const result = document.getElementById('result')
        // 绑定键盘按下事件
        window.onkeydown = function(){
             // 发送请求
             const xhr = new XMLHttpRequest();
             // 设置响应体数据类型
             xhr.responseType = 'json'
             // 初始化,调用open方法
             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
                         // 1.  手动转化数据
                         // let data = JSON.parse(xhr.response);
                         // result.innerHTML = data.name
                         // 2. 自动转换
                         // 在初始化的时候利用 xhr中的对象做一个类型设置
                         result.innerHTML = xhr.response.name;
                         
                     }
                 }
              }
           }

服务端

app.get('/json-server', (request, response)=>{
    // 设置响应头,Access-Control-Origin是名子,*是值 作用是允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    // 响应一个数据
    const data = {
        name:'jpd'
    }
    // 对对象进行字符串转换
    let str = JSON.stringify(data)
    // 设置响应体
    response.send(str)
});

请求超时与网络异常处理

 // 1. 创建对象
 const xhr =  new XMLHttpRequest
 // 超时设置
 xhr.timeout = 2000;
 // 超时回调
 xhr.ontimeout = function(){
     alert('请求超时,请稍后重试')
 }
 // 网络异常
 xhr.onerror = function(){
     alert('网络异常')
 }
 // 2. 初始化 设置请求方法和 url
 xhr.open('GET', 'http://127.0.0.1:8000/dealy')
 ----------------------------------------------------------
 /服务端加一个延时器
 app.all('/dealy', (request, response)=>{
    // 设置响应头,Access-Control-Origin是名子,*是值 作用是允许跨域
    response.setHeader('Access-Control-Allow-Origin','*')
    setTimeout(()=>{
        // 设置响应
          response.send('延时响应')
    },3000)

Promise

构造函数,实例化需要接受函数类型的值,函数还有两个形参resolve(解决),reject(拒绝)且都是函数类型的数据

// 异步任务成功时调用resolve , 失败时调用reject
const p = new Promise((resolve, reject) => {
     // 异步任务
     
     // 调用then方法
     p.then(()=> {
     // 成功时调用
     } , () => {
     // 失败时调用
     }),
});

fs读取文件

const { rejects } = require('assert');
const fs = require('fs');
const { resolve } = require('path');

// fs.readFile('Promise基本使用\content.txt',(err, data) => {
//     // 如果出错抛出错误
//     if(err) throw err;
//     // 输出文件内容
//     console.log(data.toString());
// });

let p = new Promise((resolve , rejects) => {
    fs.readFile('./第一个参数是路径', (err, data) => {
        // 如果出错
        if(err) rejects(err);
        // 如果成功
        resolve(data);
    })
})

// 调用 then
p.then(value=>{
    console.log(value.toString());
}, reason=>{
    console.log(reason);
})

封装一个AJAX请求

 <script>
        function sendAJAX(url){
            return new Promise((resolve, reject) => {
                const xhr = new XMLHttpRequest();
                xhr.open("GET,url");
                xhr.send();
                // 处理结果
                xhr.onreadystatechange = function(){
                    if(xhr.readyState === 4)
                        if(xhr.status >= 200 && xhr.status < 300){
                            // 成功的结果
                            resolve(xhr.response);
                        }else{
                            reject(xhr.status);
                        }
                }
            })
        }
        // 之后就可以直接调用这个函数
        sendAJAX('url')
        .then(value => {
            console.log(value);
        }, reason => {
            console.warn(reason);
        });
       
    </script>
promise 状态

就是实例对象的一个属性 [PromiseState]

  • pending 为决定的,是初始化的默认值
  • resolved / fullfilled 成功
  • rejected 失败 只能从初始的pending变为成功或失败

promise 工作流程

  1. new 一个实例对象在内部封装异步操作
  2. 成功就调用resolve(),然后将promise对象状态转为成功,调用then方法时调用第一个回调函数
  3. 失败就调用reject(),将对象状态转为失败,调用then方法时调用第一个回调函数
  4. 返回一个新的promise对象

axios

请求方式

  1. GET(索取):从服务器端读取数据 ---- 查(R)
  2. POST(交差):向服务器端添加新数据 -----增(C)
  3. PUT:更新服务器端已经存在的数据 ---- 改(U)
  4. DELETE: 删除服务器端数据 ----- 删(D)

请求参数

  • query参数(查询字符串参数) 参数包含在请求地址中,格式为:/xxxx?name=tom$age=18
  • params参数 也包含在请求地址中://127.0.0.1:3000/add_person/tom/18
  • 请求体参数
  1. 包含在请求体中 格式1:urlencoded 格式 name=tom&age=18,必须有对应的请求头:Content-Type:application/x-www-form-urlencoded
    格式2: json格式 {"name":"tom","age":12} 请求头对应: Content-Type:application/json
  • GET 请求不能携带 请求体参数

API的分类

  • REST API(restful 风格的API)
  1. 发送请求进行CRUD某个操作由请求方式决定
  2. 同一个请求路径可以进行多个操作
  3. 请求方式会用到GET/POST/PUT/DELETE
  • 非 REST API(restless)
  1. 请求方式不决定请求的CRUD操作
  2. 一个请求路径只对应一个操作
  3. 一般只有GET/POST
app.get('/person',(rep,res)=>{
    res.send()
})
app.get('get_person',(req,res)=>{
    res.send()
})

5月28日早9.30我是FW

学了一下postman

axios

  1. 基于promise的异步ajax请求库
  2. 支持请求取消,请求/响应数据转换
  3. 批量发送多个请求
  • 注意
  1. axios调用的返回值时Promsie实例
  2. 成功的值叫response 失败的值叫error
  3. axios成功的值是一个axios封装的response对象,服务器返回的真正数据在response.data中 4.携带params参数时,就需要子级手动拼在url中 基本GET
<body>
    <button id="btn1">点我获取所有人的信息</button>
    <!-- 
        1.axios调用的返回值时Promsie实例
        2.成功的值叫response 失败的值叫error
        3.axios成功的值是一个axios封装的response对象,服务器返回的真正数据在response.data中
     -->
    <script>
        // 获取按钮
        const btn1 = document.getElementById('btn1')
        
        // 获取所有人信息---发送一个GET请求---不携带参数
        btn1.onclick = ()=>{
            axios({
                url:'http://localhost:5000/persons', // 请求地址
                method:'GET', // 请求方式
            }).then(
                response => {console.log('请求成功了',response);},
                error => {console.log('请求失败了',error);}
           )
     ---------------------------------------------------------
     // 精简版
         axios.get('http://localhost:5000/persons').then(
             response => {{console.log('请求成功了',response);},
             error => {console.log('请求失败了',error);}
         )
        }
    </script>
   
</body>
 // 发送一个GET请求---不携带参数
        // btn1.onclick = ()=>{
        //     axios.get('http://localhost:5000/test1').then( // 请求地址
        //         response => {console.log('请求成功了',response);},
        //         error => {console.log('请求失败了',error);}
        //    )
        }
        // 获取某个人的信息---发送GET请求---不携带参数
        btn2.onclick = ()=>{
        //     axios({
        //         url:'http://localhost:5000/person',
        //         method:'GET',
        //         params:{id:personId.value} // 写的是params,但携带的是query参数
        //     }).then(
        //         response => {console.log('成功了',response.data);},
        //         error => {}
        //     )

        // 精简版
        axios.get('http://localhost:5000/person',{params:{id:persnId.value}}).then(
            response => {console.log('成功了',response.data);},
            error => {console.log();}
        )
        }