Ajax学习

AJXS学习

一.初识AJXS

1.浏览器和服务器

浏览器访问的资源存放在服务器上。

浏览器负责浏览资源,服务器负责提供资源

2.url网址

url网址的作用:标记某个资源,在网络中的唯一地址,只有通过url地址,才能定位资源的存放位置,从而成功访问到对应的资源。

url网址组成:
http(协议)😕/www.itcast.cn(主机名):80(端口号)/2018/images/logo.png(资源存放的路径)

协议:协议就是浏览器和服务器之间传输数据的规则,保证都能读懂对方发来的内容

主机名:标识服务器在互联网中的唯一地址,确保能够访问到他

端口解释:
1.端口号有效范围在0-65535之间的整数
2.标识服务器里不同服务
3.浏览器默认访问的都是80端口

路径:确定在服务器上具体位置

3.请求和响应

请求:浏览器通过网络去服务器要资源的过程
响应:服务器通过浏览器返回资源的过程

4.Ajax讲解

概念:Ajax是一种在js代码中发起一次请求并获取相应数据的技术

使用场景:
1.比如验证手机号是否在服务器已经注册过了;
2.根据输入关键字联想菜单提示数据切换;
3.根据增和删除,修改页面数据;
4.以上效果数据都在服务器上,所以浏览器刷新数据也还在

5.Ajax基础使用

Ajax是浏览器向服务器请求数据的一种技术
axios是库,对这个技术具体代码的实现

axios的使用:
1.先引入axios.js文件到自己的网页中

文件连接:https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js

2.明确axios的使用语法:

axios({
	url:'请求的URL地址',
	method:'请求的方法'
}).then((result)=>{
	//.then用来指定请求成功之后的回调函数
	//形参中的result是请求成功之后的结果
})

3.请求的url地址,就是标记资源的url网址

4.请求的方法,标记本次请求的动作不同(主要浏览器端要求什么,我们就写什么,有5种固定名字的值)

POST:向服务器新增数据
GET:从服务器获取数据
DELETE:删除服务器上的数据
PUT:更新服务器上的数据(侧重于完整更新:例如更新用户的完整信息)
PATCH:更新服务器上的数据(侧重于部分更新:例如只更新用户的手机号)

5.根据服务器的数据url网址的文档说明,我们编写代码请求一次数据

6.运行后结果,在控制台可以看到,请求并接受到此url网址返回的响应结果

例子:

    <!-- 目标:使用Ajax技术,在代码中获取图书列表数据
         技术:axios网络请求的库
         做法:
         1.先引入axios.js文件,会在window下有个axios全局方法
         2.根据axios语法来请求数据地址的资源 -->
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        axios({
            url: 'http://ajax-base-api-t.itheima.net/api/getbooks',
            method: 'GET'
        }).then((result) => {
            console.log(result)
        })
    </script>

6.Ajax传参使用

axios({
	url:'http://ajax-base-api-t.itheima.net/api/getbooks',
	method:'GET',
	params:{//携带查询参数
		//参数名:值
		id=1,
		bookname:'西游记'
	}
}).then((result)=>{
	console.log(result)
})
//查询的参数名要和服务器端对应上,会有文档使用
传递的查询参数值要真实有效,才会返回对应的结果

7.url编码

url地址中,不允许出现中文和空格等特殊符号,所以自动转换成url编码
格式:%xx%xx%xx

js内置了2个方法,可以对字符串进行url编码和url解码

//window对象内置的方法encodeURI和decodeURI
//中文->url编码
let str="西游记"
let urlStr=encodeURI(str)
console.log(urlStr);

//url编码->中文
let zhStr=decodeURI(urlStr)
console.log(zhStr)

8.POST方法

GET和POST本质上都是http请求,区别只是被贴上了不同的请求方式,后端会根据不同的方式执行不同的代码操作,所以在url?携带参数还是请求体里携带参数,要和后端代码对上即可使用

不建议在GET上携带数据发给后端,因为浏览器对GET方式传参url长度有限制

        axios({
            url: 'http://ajax-base-api-t.itheima.net/api/addbook',
            method: 'POST',
            //params:参数值对应(query查询参数)
            //data:请求体参数(body请求体)
            data: {
                bookname: '大学英语必修1',
                author: 'aaa',
                publisher: 'xx出版社'
            }
        }).then((result) => {
            console.log(result)
        })

9.请求报文

一次完整的传输过程,是一次请求对应一次响应,在传输的过程中,数据包就是报文

请求报文:规定了浏览器向服务器,以什么格式把数据发送
响应报文:规定了服务器向浏览器,以什么格式把数据返回

请求报文组成:
1.请求行:
请求方式:(GET/POST/DELETE/PUT/PATCH)
请求url:资源在服务器地址
协议版本:默认HTTP/1.1

2.请求头部:头部参数名:值

3.请求体:携带给服务器的数据

10.响应报文

响应报文组成:
1.响应行:
协议版本:默认HTTP/1.1
响应状态码:服务器返回的一个文字标识,代表本次响应的描述
响应状态描述:服务器返回的一个文字标识,代表本次响应的描述

2.响应头部:头部参数名:值

3.响应体:服务器返回的响应数据

11.响应码

1.常见的响应状态码

1XX 响应中–临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它
2XX 成功–表示请求已经被成功接受,处理已完成
3XX 重定向–重定向到其他地方(让客户端再发起一个请求以完成整个处理)
4XX 客户端错误–处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等
5XX 服务器端错误–处理发生错误,责任在服务器端,如:服务端抛出异常,路由出错,HTTP版本不支持等

200:OK 请求成功
201:Created 资源在服务器端已成功创建
302:Moved Temporarily 资源临时性重定向,响应体中不包含任何资源内容
304:Not Modified 资源在客户端被缓存(一般是css,js,图片文件)
400:Bad Request 客户端的请求方式、或请求参数有误导致的请求失败
401:Unauthorized 客户端的用户身份认证未通过,导致的此次请求失败
404:Not Found 客户端请求的资源地址错误,导致服务器无法找到资源
500:Internal Server Error 服务器内部错误,导致的本次请求失败

12.接口相关

1.接口:其实就是提供服务器的url网址,我们前面想要数据/提交数据,需要知道服务器在互联网中的唯一url地址
2.而服务器会把一些接口地址罗列整理到一个文档上
3.接口文档:就是接口使用说明书
4.接口文档格式:包含如下内容
接口名称:接口的名称,用来快速区分每个接口的作用。如:登录接口、添加图书接口
接口URL:客户端发起Ajax调用此接口时,请求的URL地址
请求方式:接口的请求方式,如:GET、POST、PUT、DELETE等
请求参数:请求此接口时,需要发送到服务器的查询参数或请求体
返回示例:当接口请求成功后,服务器响应回来的数据的基本格式
返回参数说明:接口响应结果的详细描述

13.逻辑码

位置:相应报文-响应体数据中 这次业务逻辑是否完全成功 每个数字不固定,需要和后台约定

二.表单和文件上传

1.表单

1.表单是网页里的form标签以及一些输入框和下拉菜单等等,用于手机用户输入的信息

2.表单的组成:
表单标签
表单域
表单按钮

3.表单标签指的是from标签

4.表单域:常见的有input、textarea、select等
每个表单域必须包含name属性

5.表单按钮
type的默认值就是submit

2.表单_自我提交

表单的代码

    <form>
        <div>
            <!-- 用户名 -->
            <span>用户名:</span>
            <input type="text" name="username">
        </div>
        <div>
            <!-- 密码 -->
            <span>登录密码:</span>
            <input type="password" name="password">
        </div>
        <div>
            <!-- 提交按钮 -->
            <button>提交</button>
        </div>
    </form>

2.form标签的两个属性,可以设置提交到的地址和请求的方法
action:接口的url地址,把表单采集到的数据,提交到哪个接口中
method:GET或POST,数据的提交方式(默认值为GET)

3.请求的地址和方式如下:

接口地址:http://ajax-api.itheima.net/api/data
请求方式:POST

总结:
1.form表单提交是自身特性,和Ajax没有关系
2.form表单提交,会让浏览器跳转到action指定的地址并提交数据,体验非常不好
3.Ajax+axios的提交常用,不会刷新当前页面并进行一次请求提交

3.表单_Ajax提交

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <form>
        <div>
            <!-- 用户名 -->
            <span>用户名:</span>
            <input type="text" name="username">
        </div>
        <div>
            <!-- 密码 -->
            <span>登录密码:</span>
            <input type="password" name="password">
        </div>
        <div>
            <!-- 提交按钮 -->
            <button>提交</button>
        </div>
    </form>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        //目标:Ajax提交表单
        //1.提交按钮->提交/点击事件
        //提交按钮->绑定点击事件(检测它的点击动作,它会触发默认行为)
        //表单标签->绑定提交事件
        document.querySelector('form').addEventListener('submit', e => {
            e.preventDefault()
            //2.收集表单里值
            let username = document.querySelector('input[name=username]').value
            let password = document.querySelector('input[name=password]').value
            //3.用axios提交到服务器
            axios({
                url: 'http://ajax-api.itheima.net/api/data',
                method: 'POST',
                data: {
                    username: username,
                    password: password
                }
            }).then(res => {
                console.log(res);
            })
        })
    </script>
</body>

</html>

4.表单_整体获取

一个一个标签获取,多的话会很麻烦,解决方案:使用form-serialize.js插件

引入js地址,然后此库的使用语法如下:

serialize(form表单的DOM对象)//返回值:name参数名=值&name参数名=值,例如:‘username=admin&password=123456’
serialize(form表单的DOM对象,{hash:true})//返回值:{name参数名:值,name参数名:值},例如:{username:'admin',password:'123456'}

5.文件上传

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- accept设置文件选择的类型 image/*固定写法(只能选择图片文件) -->
    <input type="file" id="myFile" accept="image/*">
    <button>点击上传文件</button>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        //目标:文件上传
        //详细:点击按钮,把选择的文件上传到服务器上
        //1.点击事件
        document.querySelector('button').addEventListener('click', e => {
            //2.获取到文件
            //拿到input标签对象.files,原地返回文件数组
            let fileList = document.querySelector('#myFile').files
            //3.把文件传递给服务器
            //如果接口文档要求传递请求体(form-data内容类型)
            //使用:window提供的FormData构造函数,来实例化一个表单容器对象
            //语法:
            /*
                let fd=new FormData()
                fd.append(参数名,前端要传的值)
                //如果还有参数名和值继续调用append添加到fd中
            */
            let fd = new FormData()
            fd.append('avatar', fileList[0])
            axios({
                url: 'http://ajax-api.itheima.net/api/file',
                method: 'POST',
                data: fd
            }).then(res => {
                console.log(res)
            })
        })
    </script>
</body>

</html>

6.请求体类型

1.application/x-www-form-urlencoded(key=value&key=value的字符串)
表单中不包含文件上传的场景,适用于普通数据的提交

2.multipart/form-data
表单中包含上传文件的场景

3.application/json
上传json格式数据

三.XHR和Promise

1.Ajax原生学习

axios.js是一个库,内部是原生js代码,实际它是对原生的代码进行了封装。
Ajax如果用原生js实现,需要使用window提供的一个构造函数,叫XMLHttpRequest
使用语法如下:

        //1.创建一个xhr对象
        let xhr = new XMLHttpRequest()
        //2.设置请求方式和请求地址 xhr.open("请求方式","请求地址")
        xhr.open('GET', 'http://ajax-api.itheima.net/api/province')
        //3.发送请求
        xhr.send()
        //4.监听load(请求成功)事件==>可以获取响应数据
        xhr.addEventListener('load', function () {
            console.log(xhr.response)//响应体数据
            //知识点:把JSON格式字符串==>转成JS数据类型
            //语法:JSON.parse(JSON字符串)
            //返回值:JS数据类型
            let result = JSON.parse(xhr.response)
            console.log(result);
        })

2.Ajax原生传参

        //1.创建一个xhr对象
        let xhr = new XMLHttpRequest()
        //2.设置请求方式和请求地址 xhr.open("请求方式","请求地址")
        xhr.open('GET', 'http://ajax-api.itheima.net/api/city?pname=辽宁省')
        //3.发送请求
        xhr.send()
        //4.监听load(请求成功)事件==>可以获取响应数据
        xhr.addEventListener('load', function () {
            console.log(xhr.response)//响应体数据
            let result = JSON.parse(xhr.response)
            console.log(result);
        })

3.JSON

1.JSON是一种数据交换格式,它本质上是用字符串的方式来表示对象或数组类

2.用字符串的方式来表示的对象或数组类型的数据,叫做JSON数据
对象格式JSON字符串
key必须用双引号包起来

'{"userName":"小马","age":16,"sex":"男"}'

数组格式JSON字符串

'["小马",16,"男"]'

3.相互转换

    <script>
        //1.JS数据类型==>JSON字符串
        //语法:JSON.stringify(JS数据类型)
        //返回值:JSON字符串
        let obj = {
            username: '小马',
            age: 16,
            sex: '男'
        }
        console.log(JSON.stringify(obj));
        //2.JSON字符串==>JS数据类型
        //语法:JSON.parse(JSON字符串)
        let jsonStr = '{"username":"小马","age":16,"sex":"男"}'
        console.log(JSON.parse(jsonStr))
    </script>

4.同步异步

同步:在原地需要有结果,才能继续向下
异步:交给浏览器去执行,不必在原地等待结果,主线程会先继续往下执行其他代码

异步:定时器,Ajax请求,事件绑定

5.回调函数

异步一般需要耗时,且不会阻塞主线进程代码往下执行
在JS中,只有用函数调用的方式,才能让某一段代码去执行
所以异步代码都有一个函数体,这个函数体里面代码都是等待这个异步任务有结果后执行
把一个函数当作实参传递进去,将来特定的时机,在调用的这个函数内,回调我们传入的函数调用,这个动作就叫回调函数

function theFn(fn){
	fn()//代码执行到这句话,会回调theFn()里函数体执行,这个过程叫回调函数
}
theFn((=>{//此箭头函数作为实参值传递给了theFn的形参变量fn上
	console.log('回调函数执行');
}))

6.回调地狱

回调函数中嵌套回调函数,不方便阅读和修改

举例

    <script>
        function myAjax(url, fn) {
            let xhr = new XMLHttpRequest()
            xhr.open('GET', url)
            xhr.send()
            xhr.addEventListener('load', () => {
                fn(JSON.parse(xhr.response))
            })
        }
        //1.请求省份列表
        myAjax('http://ajax-api.itheima.net/api/province', res => {
            let pname = res.data[5]
            //2.请求城市列表
            myAjax(`http://ajax-api.itheima.net/api/city?pname=${pname}`, res => {
                let cname = res.data[9]
                //3.请求地区列表
                myAjax(`http://ajax-api.itheima.net/api/area?pname=${pname}&cname=${cname}`, res => {
                    console.log(res)
                })
            })
        })
    </script>

7.Promise语法学习

ES6新出的一个构造函数,为了解决回调地狱

语法:

let 变量 = new Promise((resolve,reject)=>{
	//resolve和reject是Promise提供的两个函数
	//写一些代码(同步/异步)都可以,你想返回出去结果
	
	//resolve('成功的结果')
	//reject('失败的结果')
})
	变量.then(res=>{
		//接收此Promise对象内,返回出来的成功结果
	}).catch(err=>{
		//接收此Promise对象内,返回出来的失败结果
	})
	运行:
	1.new Promise后原地留下一个Promise对象(承诺),承诺将来会有一个成功/失败的结果给你返回使用
	2.它会立即执行new Promise()小括号里所有代码

8.Promise的三种状态

  1. new Promise原地有个Promise§,状态:‘pending’(准备) 通过打印查看它的标记
    2.立刻执行new Promise()里函数体所有代码,并准备resolve和reject函数
    3.给Promise对象§,添加.then和.catch函数,等待结果
    4.Promise对象内,当调用了resolve(),会把当前Promise对象,状态:‘fulfilled’(成功),内部会回调then()里面函数体执行
    5.Promise对象内,当调用了reject(),会把当前Promise对象,状态:‘rejected’(失败),内部会回调.then()里面函数体执行

9.链式调用

        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('成功1')
            }, 2000)
        })
        let p2 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('成功2')
            }, 2000)
        })
        p.then(res => {
            console.log(res);//如果return一个promise对象,会被下一个then接收
            return p2
        }).then(res => {
            console.log(res)
        })
        //两个promise一起打印

10.解决回调地狱

        function myAjax(url) {
            return new Promise((resolve, reject) => {
                let xhr = new XMLHttpRequest()
                xhr.open('GET', url)
                xhr.send()
                xhr.addEventListener('load', () => {
                    resolve(JSON.parse(xhr.response))
                })
            })
        }
        let pname=''
        //1.拿到省份
        let p=myAjax('http://ajax-api.itheima.net/api/province')
        p.then(res=>{
            pname = res.data[5]
            //2.拿到城市
            return myAjax('http://ajax-api.itheima.net/api/city?pname=${pname}')
        }).then(res=>{
            let cname = res.data[9]
            return myAjax(`http://ajax-api.itheima.net/api/area?pname=${pname}&cname=${cname}`)
        }).then(res=>{
            console.log(res)
        })

11.promise的方法

all方法
语法:

Promise.all()
作用:它把多个Promise对象合并成一个大的Promise对象
返回值:大的Promise对象
这个大的Promise对象的结果,还是一个数组
Promise.all([小Promise对象,小Promsie对象,小Promise对象])
特点:需要所有小的Promise对象成功后才会触发大的Promise对象成功的then
注意:万一有失败了,就会让大的Promise对象直接状态变成失败状态

race方法
语法:

Promise.all([小Promise对象,小Promsie对象,小Promise对象])
作用:它可以把多个Promise对象合并成一个大的Promise对象,有一个小的Promise对象成功了,这个大的Promise对象直接为成功状态(其他不看),大的Promise对象的结果,直接是成功的这个小的Promise对象的成功结果

四.ES8和EventLoop

1.async和await

语法:

async function 函数名(){
	const result = await Promise对象
}

举例:

        //aiait只能在被async修饰的函数内
        let p=new Promise((resolve,reject)=>{
            setTimeout(() => {
                resolve('成功的值')
            }, 2000);
        })
        async function myFn(){
            const result = await p
            console.log(result)
        }
        myFn()
        const youFn= async()=>{
            const result=await p
            console.log(result)
        }
        youFn()

注意事项:
1.await必须用在被async修饰的函数内
2.async修饰后,此函数会被作为异步函数,在此函数中,遇到await会暂停代码往下,但不影响外面继续执行同步流程
3.await后面一般用Promise对象,但是也可以跟其他类型的数据。如果后面跟其他类型数据,把此值作为await提取成功的结果在原地直接使用;如果跟Promise对象,需要等待Promise对象内,resolve返回成功的结果,被await提取在原地使用
4.await不能获取到Promise对象内失败的结果,需要借助try+catch代码块来捕获

2.解决回调地狱

        const getListFn = async () => {
            const res = await myAjax('http://ajax-api.itheima.net/api/province')
            const pname = res.data[5]
            const res2 = await myAjax('http://ajax-api.itheima.net/api/city?pname=${pname}')
            const cname=res.data[9]
            const res3= myAjax(`http://ajax-api.itheima.net/api/area?pname=${pname}&cname=${cname}`)
            console.log(res3)
        }

3.EventLoop事件循环

js是单线程执行的脚本语言,同一时间只能做一件事
单线程执行任务队列,如果有一个耗时任务,后续会一直等待。防止这个问题,异步代码由js委托给宿主环境(node环境,浏览器)等执行

几个概念:
1.JS引擎(c++的代码),嵌入在浏览器软件内
作用:阅读+解析+执行,我们编写的js代码并运算结果
宿主:浏览器

2.js引擎里执行栈
(1)先从上到下逐行执行代码,遇到同步代码,等待结果并使用
(2)遇到异步代码,则交给宿主环境,主线程继续执行下一句
(3)宿主环境(异步任务)有了结果,会“先”把“回调函数”装入任务队列中排队
(4)执行栈空闲,会把任务队列里回调函数推入执行栈执行

3.事件循环
当执行栈空闲,调度任务队列里回调函数执行,再次空闲,再调度的循环过程,就叫事件循环

4.微任务和宏任务

微任务代码:宿主环境是JS引擎 Promise等 优先执行

宏任务代码:宿主环境是浏览器 script 事件 网络请求 定时器

异步任务的回调函数,才会放入任务队列中,等待被执行栈调用
微任务在宏任务之前被执行

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值