Ajax
一,定义
概念:
AJAX (阿贾克斯 Asynchronous Javascript And Xml ) 异步 JavaScript 和 XML,是指一种创建交互式网页应用的网页开发技术,能发送 HTTP 请求和接收 HTTP 响应;
特点:
1,默认是异步执行
2,能够实现局部刷新
3,不能直接跨域请求
二,浏览器的同源政策:
1,为什么会有?
出于安全性的考虑而制定的安全策略,它只允许对应的两者是同源的内容进行访问和交互;不同源的内容不允许访问;
2,什么是同源?
如果两个 地址 URL 的 (协议)protocol、port(端口,如果有指定的话)和 host(主机/域名)都相同的话,则这两个 URL 是同源。
3,什么情况下会触发同源政策,导致无法访问的跨域问题?
异步请求-Ajax;
4,解决跨域问题的方式
a,JSONP(非官方跨域数据交互协议);前端
b,由服务器端支持跨域,添加请求头(xml.setRequestHeader);后端
c, 服务器代理 前端常见使用 nodejs 的代理;
状态码:
0: 请求未初始化 1: 服务器连接已建立 2: 请求已接收 3: 请求处理中 4: 请求已完成,且响应已就绪
响应码:
1xx 信息响应 2xx 成功响应 200 3xx 重定向 304 4xx 客户端错误 404 5xx 服务端错误
三,实现流程
1,创建 Ajax 请求对象
//兼容写法
function createXHR() {
//IE7+ 谷歌, 火狐, Safari等
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
return new ActiveXObject("Microsoft.XMLHTTP"); //IE6
}
//创建对象
let xml = createXHR();
2,初始化请求,设置请求地址
//请求方式:get,post; 地址:服务器地址; 执行方法:true:异步,false:同步;
xml.open(请求方式,地址,执行方法);
3,设置监听
xml.onreadyStatechange = function () {
//判断是否成功请求
if (xml.readyState == 4 && /^2\d/.test(xml.status)) {
console.log(xml.response);
//接收响应的主体
}
};
4,发送请求
xml.send();
5,接收响应
xml.response();
6,POST 方式的响应头设置
//设置请求头的类型,注意第二个参数, / 后面是发送过去的类型,一般是如下表单类型
xml.setRequestHeader(
"content-type",
"application/x-www-form-urlencoded; charset=utf-8"
);
7,请求数据存放的位置
//采用GET方法的,存放在 xml.open()里;
xml.open(请求方式,地址?数据,请求执行方法);
//在地址后用 ? 连接,后接数据,数据内容使用键值对,不同键值对使用 & 连接;
xml.open("GET","https://jsonplaceholder.typicode.com/todos?uname=l&upwd=123")
//采用POST方法的,存放在 xml.send()里;
xml.send(数据);
//在括号内直接写数据,数据内容使用键值对,不同键值对使用 & 连接;
xml.send("uname=l&upwd=123")
四,Ajax 属性和方法
1,监听:.onreadyStatechange
xml.onreadyStatechange = function () {
//该方法会在 XMLHttpRequest 的 readyState 属性发生改变时触发
};
五,ASONP 方法解决跨域问题
JSONP(非官方跨域数据交互协议);
1,实现的简述原理:使用 script 的 src 引入需要访问的地址,它使用的是 get 请求;
2,实现过程:
a,封装回调函数;b,将函数添加到 windwon 方法;c,使用 script 引入目标地址;
3,JSONP 的封装(使用过 promis)
function jsonp({
url, //链接地址
callback, //回调函数的参数名
param, //参数
}) {
return new Promise((resolve, reject) => {
//创建函数名,要随机但必须要以字母开头
let fnName = "fn" + Date.now() + parseInt(Math.random() * 1000);
//将函数名和函数设置为window的方法
//使用promise封装,成功时直接返回
window[fnName] = resolve;
//首先创建script标签
let js = document.createElement("script");
//将回调函数名和回调函数加到url里
url += `?${callback}=${fnName}`;
//设置参数,加入到地址里
let paramValue = "";
for (let key in param) {
paramValue += `&${key}=${param[key]}`;
}
url += paramValue;
//最后设置参数加入到script中
js.src = url;
document.body.appendChild(js);
//优化,加载完成后删除
js.onload = function () {
js.remove();
delete window[fnName];
};
//加载失败时,出错的状态
js.onerror = () => reject("加载错误");
});
}
4,案例:使用 JSONP 和接口实现百度搜素框效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!--引入已经封装好的JSONP函数-->
<script src="./jsonp.js"></script>
<input type="text" id="ipt" />
<ul id="box"></ul>
<button id="btn">搜索</button>
<script>
//获取元素
let box = document.getElementById("box");
let inp = document.getElementById("ipt");
let li;
inp.onkeyup = chock(function () {
//如果input里没有内容则清除所有
if (inp.value.trim() == "") {
box.remove();
return;
}
//处理列表框
box.remove();
box = document.createElement("ul");
document.body.appendChild(box);
//数据处理
jsonp({
url: "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su",
callback: "cb",
param: {
wd: inp.value,
},
}).then((res) => {
//使用promise.then方法,返回成功的结果;
if (res != null) {
for (let i of res.s) {
li = document.createElement("li");
li.innerText = i;
box.appendChild(li);
}
//点到哪个,把哪个的内容赋予第一个input
let list = document.querySelectorAll("li");
for (let v of list) {
v.onclick = function () {
for (let i = 0; i < list.length; i++) {
list[i].style.background = "";
}
this.style.background = "red";
inp.value = this.innerText;
};
}
}
});
}, 200);
//点击btn时,获取input里的内容进行搜索
btn.onclick = function () {
let text = inp.value;
console.log(text);
};
//节流
function chock(fn, wait) {
let timer = null;
return function () {
if (timer) return;
timer = setTimeout(() => {
fn();
timer = null;
});
};
}
</script>
</body>
</html>