Ajax
了解AJAX
- AJAX: Asynchronous Javascript And Xml,Ajax 技术的核心是XMLHttpRequest对象(简称XHR),这是由微软首先引入的一个特性,其他浏览器提供商后来都提供了相同的实现
*Ajax起源:
最早出现在2005年的google搜索建议
- ajax优点
- 增加速度:减轻服务器的负担,按需加载数据,最大程度的减少冗余请求
- 改善的用户体验:局部刷新页面,减少用户等待时间,带来更好的用户体验
- 页面和数据分离:前后端分离,操作更灵活,后期维护更方便
- 后端语言和服务器配置
- php + Apache + mySQL
- NodeJS + MongoDB
- Java + tomcat + Oracle
- .NET + IIS + SQL Server
json
json数据(json字符串)
1 | {"id" : 21465461461461, "name": "张三"},[{"id" : 21465461461461, "name": "张三"}] |
json字符串与对象的转换
1 | //(一)json字符串转成对象的转换 |
了解json文件存在的意义
1 | //模拟数据(与后端先商量) |
Ajax请求步骤
创建请求对象,返回一个异步请求对象
var xhr = new XMLHttpRequest();
处理服务器返回数据
1 | xhr.onreadystatechange = function(){ |
设置请求参数,建立与服务器连接
1 | xhr.open("get", "http://localhost/api/ajaxtest", true); |
向服务器发送请求
xhr.send(null);
案例:演示向goodslist.json请求数据
XMLHttpRequest对象属性方法
open(type,url(同源策略),async(同步、异步))
1 | 1.open(type,url,async): 建立与服务器的连接 |
send(data)
1 | 2.send(data): 向服务器发送请求 |
**在请求收到服务器的响应后,响应的数据会自动填充xhr 对象的属性,相关的属性简介如下:
readyState
1 | 0 - (未初始化)尚未调用open()方法。 |
responseText
保存服务器返回的数据(从服务器返回的数据是“字符串”)。
status
1 | * 响应的HTTP 状态。 |
php本地数据操作
获取前端数据
1 | $_GET 获取前端用get方式传递过来的数据(url地址后面数据也能被获取) |
文件的读取与写入
fopen(path,mode):打开文件
使用fopen函数打开文件时,你首先需要明确打开文件的模式:
1.将数据写入文件,亦或者读写文件
2.考虑如果文件中已经存在相关数据,你是覆盖原有文件中的数据呢,还是仅仅将新数据添加至文件末尾
文件模式:
- r 以只读方式打开文件,从文件头开始读
- r+ 以读写方式打开文件,写入时以追加的方式写入文件
- w 以写入方式打开文件,从文件头开始写。文件不存在则尝试创建,若存在,则先删除文件中的内容
- w+ 以读写方式打开文件,从文件头开始读写。文件不存在则尝试创建,若存在,则先删除文件中的内容
- a 以写入方式打开,从文件末尾开始追加写。如果文件不存在则尝试创建
- a+ 以读写方式打开,从文件末尾开始追加写入或者读。如果文件不存在则尝试创建。
fread(file,length):读取内容
fwrite(file,json字符串):写入内容
fclose(file):关闭文件,避免资源占用
filesize(path):读取文件字符长度
//1.以读取模式打开文件
$path = './data/weibo.json'
$myfile = fopen($path, 'r');
//2.读取文件内容
$content = fread($myfile, filesize($path));
//3.关闭文件,减少资源占用
fclose($myfile);
1 | echo返回数据 |
案例:微博点赞
1 | //(html页面)1.发起ajax请求,将weibo.json的内容返回到页面 |
补充:eval的使用
1 | var json = '{"name":"lemon","age":18}'; //标准json字符串 |
讲解:ajax的来历及同源策略、同步异步
案例:用户名验证
username.onblur = function(){
let _username = username.value;
let status = [200,304];
let xhr = new XMLHttpRequest();
//xhr.onload意思为数据请求完成后,等同于xhr.readystate==4的状态
xhr.onload = function(){
if(status.includes(xhr.status)){
let res = xhr.responseText;//fail,success
if(res === 'fail'){
username.nextElementSibling.innerHTML = `${_username}太受欢迎,你走吧`;
}else{
username.nextElementSibling.innerHTML = `恭喜你绿了`;
}
}
}
xhr.open('get','../api/checkname.php?username='+_username,true);
xhr.send();
}
//php
//1.数组存放已经存在的用户名
$userlist = array('张三','李四','王尼玛','奥巴马','laoxie','lemon');
//2. 获取前端传来的用户名
$username = isset($_GET['username']) ? $_GET['username'] : null;
//3. 判断前端传来的用户名是否已存在数组内
$res = in_array($username, $userlist);
if($res){
// 用户名已存在,注册失败
echo "fail";
}else{
echo "success";
}
案例:分页数据加载
1 | //html页面: |
ajax跨域解决方案
JSONP
- JSONP 是JSON with padding(填充式JSON 或参数式JSON)的简写。
- JSONP是一种可以绕过浏览器的安全限制,从不同的域请求数据的方法。
- JSONP请求不是ajax请求,是利用script标签能加载其他域名的js文件的原理,来实现跨域数据的请求
- 局限性:
- 只能为get请求
- 接口必须有回调函数的执行
演示:使用script标签其他js文件调用本地js的某个函数
1 | //html页面: |
演示:使用script标签其他php文件调用本地js的未知名方法,返回数据
1 | //html页面: |
案例:利用JSONP原理调用百度建议
msg.oninput = function(){
let _msg = msg.value;
clearTimeout(timer);
timer = setTimeout(()=>{
let script = document.createElement('script');
script.src='https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/sujson=1&cb=getData&wd='+_msg;
document.body.appendChild(script);
},500);
}
window.getData = function(data){
suggest.innerHTML = data.s.map(item=>{
return `<li>${item}</li>`
}).join("");
}
})
//原理性代码:
//1.script的src中回调函数的传递
script.src='https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/sujson=1&cb=getData&wd='+_msg;
//2.声明全局函数
window.getData = function(data){处理数据}
CORS
CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing),它允许浏览器向跨源服务器发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
1.Access-Control-Allow-Origin
header('Access-Control-Allow-Origin: * ');
该字段是必须的。需要在后端响应头添加词字段,值要么是一个*,表示接受任意域名的请求,要么指定一个域名http://localhost。
2.Access-Control-Allow-Methods
3.Access-Control-Allow-Headers
header('Access-Control-Allow-Methods:POST');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
案例:天气预报
//1.直接利用ajax请求得到数据
let xhr = new XMLHttpRequest();
let status = [200,304]
xhr.onload = function(){
if(status.includes(xhr.status)){
let res = JSON.parse(xhr.responseText)
console.log(res.data);
//拿到数据,可以渲染部分到页面上
let title = document.createElement('h2');
title.innerHTML = res.data.city + '天气预报';
let tips = document.createElement('p');
tips.innerHTML = res.data.ganmao;
let ul = document.createElement('ul');
ul.innerHTML = res.data.forecast.map(item=>{
return `<li>
<h4>${item.date}</h4>
<p>${item.low} / ${item.high}</p>
<p class="type">${item.type}</p>
</li>`
}).join('\n');
// 清空内容
weather.innerHTML = '';
weather.appendChild(title);
weather.appendChild(tips);
weather.appendChild(ul);
}
}
xhr.open('get','http://wthrcdn.etouch.cn/weather_mini?city=广州',true);
xhr.send();
//2.配合文本框实现,得到不同城市的天气预报
city.onblur = function(){
let _city = city.value.trim();
if(_city.length === 0){
return;
}
xhr.open('get','http://wthrcdn.etouch.cn/weather_mini?city='+_city,true);
xhr.send();
}
演示:百度地图
服务器代理
后端不存在跨域问题,所以可以利用后端间接获取其他网站的数据
Promise
Promise是一个构造函数,所谓的Promise对象,就是通过new Promise()实例化得到的对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。
Promise 的三种状态
Pending(未完成)可以理解为Promise对象实例创建时候的初始状态
Resolved(成功) 可以理解为成功的状态
Rejected(失败) 可以理解为失败的状态