day22 ajax

关键词

  • 线程(线程是进程的最小单位 JavaScript是单线程的语言) 单线程解析 渲染线程也是单线程

  • 进程(正在运行的程序)

  • 同步 (一个线程执行)(同步阻塞)
    上一个没有做完 下一个不能执行

  • 异步 (多个线程)
    上一个和这一个没关系

概述
AJAX(asynchronous Javascript and xml)异步的Javascript和xml.他是用于发送http请求的,他可以发送异步请求.他可以完成页面局部刷新功能 (在整个页面不刷新的前提下 发送对应的请求改变对应的部分的dom),他的核心对象为XMLHttpRequest(xhr)

请求流程
在这里插入图片描述
Ajax的代码实现

//新建请求对象
var xhr = new XMLhttpRequest()
//以对应的请求方式打开对应的地址
xhr.open('get',http://jsonplaceholder.typicode.com/todos)
//发送请求
xhr.send()
//监听请求状态的变化  readyState (1 - 5   1是准备发送  2 发送完成  3 发送完成 数据准备接收 4收据接收完毕  5错误)
xhr.onreadystatechange = ()=>{
	进行状态判断  4 是收据接收完毕
	if(xhr.readyState==4){
	//responseText 表示返回的文本 (字符串)
	console.log(xhr.responseText)
	}
}

属性
readyState 状态码
(1 - 5 1是准备发送 2 发送完成 3 发送完成 数据准备接收 4收据接收完毕 5错误)
console.log(xhr.readyState);

status http状态码(只有发送http协议都会有)
取值100- 599
1开头(表示成功但需要后续操作)
2开头 (成功 200)
3开头 (重定向304)
4开头(表示客户端错误 404找不到页面 403权限不够)
5开头(表示服务器错误 500)

XMLHttpRequest对象的相关属性及方法

属性:

  • responseText 响应的文本
  • responseXML 响应的XML
  • responseType 响应的类型
  • responseURL 响应的地址
  • timeout 设置请求的超时时间
  • readyState 状态码
  • status http状态码

方法:

  • open 打开一个请求
  • send 发送一个请求
  • setRequestHeader 设置请求头
  • getResponseHeader 获取响应头

事件
onreadyStatechange 监听改变的状态

var xhr = new XMLHttpRequest()
//属性
//readyState 对应的xhr对象的一个状态码(这个状态码只有xhr才有)
// 0 没有请求 1准备发送 2请求已经发送 3请求发送完毕 准备接收响应数据 4响应接收完毕
console.log(xhr.readyState);
//status http状态码 (只要发送http请求都会有)
// 取值为100 - 599
// 1开头(表示成功 但是需要后续操作)
// 2开头 (成功 200)
// 3开头 (重定向 304)
// 4开头 (表示客户端错误 404(找不到页面) 403(权限不足))
// 5开头 (表示服务器错误 500)
console.log(xhr.status);
//responseText 响应的文本
console.log(xhr.responseText);
//responseXML 响应的xml
console.log(xhr.responseXML);
//响应类型
console.log(xhr.responseType);
//响应的地址
console.log(xhr.responseURL);
//设置请求的超时时间
console.log(xhr.timeout );
//方法
//设置请求 open 请求方式 请求地址
xhr.open('get','')
//发送方法 里面的传递的参数是设置给请求体的内容
xhr.send('')
//请求头相关 设置请求头 通过键值对的方式 键 值 都是字符串
xhr.setRequestHeader('Connection','keep-alive')
//响应头获取 通过key来获取value
xhr.getResponseHeader('Content-type')
//事件 当前状态改变的事件
xhr.onreadystatechange = ()=>{
//判断readyState为4 http状态码以2开头
if(xhr.readyState == 4 && /^2\d{2}$/.test(xhr.status)){
//接收数据进行处理
}
}

数据渲染案例

<button>请求数据</button>
<ul>
</ul>
<script>
//获取ul
var ul = document.querySelector('ul')
// http://jsonplaceholder.typicode.com/todos?_limit=10&_page=2
//get请求的传参使用?和&做拼接 search传参(query传参)
//第一个前面要添加? 对应的多个参数使用&连接
//get传参时使用地址的拼接来传递参数
// _limit表示 个数 _page表示页数
document.querySelector('button').onclick = function(){
//请求数据
var xhr = new XMLHttpRequest()
//设置请求地址
xhr.open('get','http://jsonplaceholder.typicode.com/todos')
//发送请求
xhr.send()
//接收响应数据
xhr.onreadystatechange = ()=>{
if(xhr.readyState == 4 && /^2\d{2}$/.test(xhr.status)){
//接收数据
var str = xhr.responseText
//将字符串转为对应的对象
var result = JSON.parse(str)
//渲染
//遍历result进行渲染
result.forEach(item => {
ul.innerHTML += ` <li>
id: ${item.id}
${item.title}
${item.completed?'�':'�'}
</li>`
});
}
}
}
</script>

get请求封装

//封装一个对应的get请求的方法
//请求地址 参数 (以对象传递) 对应的处理不一样
export function get(url,params={},callback){
//判断url地址是否传递 如果没有传递直接报错
if(!url){
throw new Error('地址必须传递')
}
//新建请求对象
let xhr = new XMLHttpRequest()
//设置请求地址 (拼接参数到url)
//遍历对象中所有的属性
for(let key in params){
// {_limit:10,_page:1}
// http://jsonplaceholder.typicode.com/todos?_limit=10&_page=1
//判断url里面是否存在? 如果没有就加上
if(!url.includes('?')){
url+=`?${key}=${params[key]}`
}else{
url+=`&${key}=${params[key]}`
}
}
xhr.open('get',url)
//发送请求
xhr.send()
//监听请求状态改变
xhr.onreadystatechange = ()=>{
//判断是否成功
if(xhr.readyState == 4 && /^2\d{2}$/.test(xhr.status)){
//成功调用回调函数传递参数出去
//先转为对象再传递出去
callback(JSON.parse(xhr.responseText))
}
}
}

分页渲染示例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
<ul>
</ul>
<script type="module">
import {get} from './ajax.js'
//获取ul
var ul = document.querySelector('ul')
//获取所有按钮
var btns = document.querySelectorAll('button')
//遍历按钮添加事件
Array.from(btns).forEach((v,i)=>{
v.onclick = ()=>{
get('http://jsonplaceholder.typicode.com/todos',{
_
limit:10,
_
page:i+1
},(res)=>{
ul.innerHTML = ''
res.forEach(item => {
ul.innerHTML += ` <li>
id: ${item.id}
${item.title}
${item.completed?'�':'�'}
</li>`
});
})
}
})
</script>
</body>
</html>

简单的post请求

<!-- action 提交的地址 method 提交的方式 -->
<form action="https://jsonplaceholder.typicode.com/posts" method="post">
<!-- 如果使用action进行提交 那么提交的内容在对应的输入框中 提交的时候以key value提
交
name属性表示的是key 对应的value是输入框的值
<input type="text" name="uname">
<input type="password" name="upwd">
<button type="submit">登录</button>
</form>
<!-- 通过form发送的post请求 需要指定请求方式 这个请求的数据以表单形式发送的
没有指定请求方式 默认以get方式提交
数据暴露在地址栏 他是通过?&进行拼接 (对应的get请求提交的数据通过字符串的形式)
get请求提交的数据有限 (2kb)
get请求因为在地址栏 所以他会有历史记录
get请求是不安全
只有指定为post才会以post请求提交
post请求 数据是会封装成表单对象存储在对应的请求体中进行提交
数据提交的容量 要远远大于get请求的
而post请求没有历史记录
post安全性要高于get请求
--
>
<!-- 异步的post请求 -->
<script>
//获取form表单
document.forms[0].onsubmit = ()=>{
//获取input框的数据
var inputs = document.querySelectorAll('input')
var username = inputs[0].value
var password = inputs[1].value
//新建请求对象
var xhr = new XMLHttpRequest()
//打开连接
xhr.open('post','https://jsonplaceholder.typicode.com/posts')
//设置请求头 告诉后台的我的内容为表单形式
//内容的类型为表单形式
xhr.setRequestHeader('Content-type','application/x-www-form-
urlencoded')
//发送数据 key=value&key=value send里面的数据放入在请求体
xhr.send(`username=${username}&password=${password}`)
//监听状态改变
xhr.onreadystatechange = ()=>{
if(xhr.readyState == 4 && /^2\d{2}$/.test(xhr.status)){
console.log(xhr.responseText);
}
}
//禁止默认行为
return false
}
</script>

post请求封装

//封装post请求
export function post(url,params={},callback){
//判断url地址是否传递 如果没有传递直接报错
if(!url){
throw new Error('地址必须传递')
}
//新建请求对象
let xhr = new XMLHttpRequest()
//设置请求地址 (拼接参数到url)
xhr.open('post',url)
//设置请求头
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
//数据拼接发送
let paramsStr = ""
for(let key in params){
// {_limit:10,_page:1}
// _limit=10&_page=1
paramsStr +=
`
&${key}=${params[key]}`
}
//删除最前面的&
paramsStr = paramsStr.substring(1)
//发送请求
xhr.send(paramsStr)
//监听请求状态改变
xhr.onreadystatechange = ()=>{
//判断是否成功
if(xhr.readyState == 4 && /^2\d{2}$/.test(xhr.status)){
//成功调用回调函数传递参数出去
//先转为对象再传递出去
callback(JSON.parse(xhr.responseText))
}
}
}

ajax封装

//将post请求和get请求抽取
export const ajax = (url,option,callback)=>{
//判断是否具备url
if(!url){
throw new Error('地址必须传递')
}
//你传什么就改什么 不传为默认值
let defaultOption = {
method:'get',
data:{},
contentType:'application/json',
timeout:'3000'
}
//遍历对象里面key
for(let key in option){
//默认的选项里面存在这个key
if(defaultOption[key]){
//用option里面对应key的值来替换默认值
defaultOption[key] = option[key]
}
}
//新建请求对象
let xhr = new XMLHttpRequest()
//判断是get请求还是post请求
if(defaultOption.method == 'get'){
//设置请求地址 (拼接参数到url)
//遍历对象中所有的属性
for(let key in defaultOption.data){
// {_limit:10,_page:1}
// http://jsonplaceholder.typicode.com/todos?_limit=10&_page=1
//判断url里面是否存在? 如果没有就加上
if(!url.includes('?')){
url+=`?${key}=${defaultOption.data[key]}`
}else{
url+=`&${key}=${defaultOption.data[key]}`
}
}
}
xhr.open(defaultOption.method,url)
//设置请求头
xhr.setRequestHeader('content-type',defaultOption.contentType)
//判断是否为post请求
if(defaultOption.method == 'post'){
//数据拼接发送
let paramsStr = ""
for(let key in defaultOption.data){
// {_limit:10,_page:1}
// _limit=10&_page=1
paramsStr +=
`
&${key}=${defaultOption.data[key]}`
}
//删除最前面的&
paramsStr = paramsStr.substring(1)
//发送请求
xhr.send(paramsStr)
}else{
//发送请求
xhr.send()
}
//监听请求状态改变
xhr.onreadystatechange = ()=>{
//判断是否成功
if(xhr.readyState == 4 && /^2\d{2}$/.test(xhr.status)){
//成功调用回调函数传递参数出去
//先转为对象再传递出去
callback(JSON.parse(xhr.responseText))
}
}
}

ajax promise封装

//将post请求和get请求抽取
export const ajax = (url,option)=>{
//判断是否具备url
if(!url){
throw new Error('地址必须传递')
}
//你传什么就改什么 不传为默认值
let defaultOption = {
method:'get',
data:{},
contentType:'application/json',
timeout:'3000'
}
//遍历对象里面key
for(let key in option){
//默认的选项里面存在这个key
if(defaultOption[key]){
//用option里面对应key的值来替换默认值
defaultOption[key] = option[key]
}
}
//新建请求对象
let xhr = new XMLHttpRequest()
//判断是get请求还是post请求
if(defaultOption.method == 'get'){
//设置请求地址 (拼接参数到url)
//遍历对象中所有的属性
for(let key in defaultOption.data){
// {_limit:10,_page:1}
// http://jsonplaceholder.typicode.com/todos?_limit=10&_page=1
//判断url里面是否存在? 如果没有就加上
if(!url.includes('?')){
url+=`?${key}=${defaultOption.data[key]}`
}else{
url+=`&${key}=${defaultOption.data[key]}`
}
}
}
xhr.open(defaultOption.method,url)
//设置请求头
xhr.setRequestHeader('content-type',defaultOption.contentType)
//判断是否为post请求
if(defaultOption.method == 'post'){
//数据拼接发送
let paramsStr = ""
for(let key in defaultOption.data){
// {_limit:10,_page:1}
// _limit=10&_page=1
paramsStr +=
`
&${key}=${defaultOption.data[key]}`
}
//删除最前面的&
paramsStr = paramsStr.substring(1)
//发送请求
xhr.send(paramsStr)
}else{
//发送请求
xhr.send()
}
return new Promise((resolve,reject)=>{
//监听请求状态改变
xhr.onreadystatechange = ()=>{
//判断是否成功
if(xhr.readyState == 4){
//成功调用resolve传递数据
//先转为对象再传递出去
if(/^2\d{2}$/.test(xhr.status)){
resolve(JSON.parse(xhr.responseText))
}
if(/^4\d{2}/.test(xhr.status)){
reject()
}
}
}
//如果xhr对象有错也调用reject
xhr.onerror = ()=>{
reject()
}
})
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值