ajax跨域、json及常用数组函数
1 ajax
相关概念解析:
(1)同步:前端发请求,必须等到后端响应完成,才允许发送另一个请求
异步:前端发请求后,不需等待后端响应结果继续执行,后端响应完成通过事件通知前端处理
(2)XMLHttpRequest对象
a:创建xhr对象:const xhr = new XMLHttpRequest();
b:配置xhr参数:xhr.open(type,url);
c:处理xhr响应:xhr.onload = () => {};
d:发送xhr请求:xhr.send();
(3)xhr对象常用属性
responseType:设置响应类型
response:响应正文
(4)xml对象常用方法
open(type,url):配置请求参数
send(data/null):发送请求,默认值是null
(5)xhr对象常用事件
load():请求成功
error():请求失败
1.1 get请求
代码前准备:
搭建hello服务器,个人用的是免费工具pupstudy,前端html与后端php在同一个目录文件
前端页面代码:
<button>ajax-get</button>
<p></p>
//将script脚本写在前端页面里
<script>
const btn =document.querySelector("button");
btn.onclick = () => {
//严格按照xhr对象的四个步骤走
//1 创建xhr对象
const xhr = new XMLHttpRequest();
//2 配置xhr参数,open(type:访问方式,url:访问目标地址),
xhr.open("get","test1.php?id=2");
xhr.responseType = "json";
//3 处理xhr响应:
//成功
xhr.onload = () => {
console.log(xhr.response);
//dom:将响应结果渲染到页面中
let user = `${xhr.response.name}(${xhr.response.email})`;
document.querySelector("p").innerHTML = user;
};
xhr.onerror = () => console.log("Error");
};
//4 发送xhr请求
xhr.send(null);
</script>
后端代码
//使用二维数组模拟用户数据表信息
$users = [
['id'=>1, 'name'=>'天蓬','email'=>'tp@php.cn','password' => md5('123456')],
['id'=>2, 'name'=>'灭绝','email'=>'mj@php.cn','password' => md5('abc123')],
['id'=>3, 'name'=>'西门','email'=>'xm@php.cn','password' => md5('abc888')],
];
// 查询条件
$id = $_GET['id'];
//在id组成的数组中查询是否存在指定的id,并返回对应的键名
//array_column($users,'id')在users数据里面拿出id一列
//array_search($id,array):在array数组中查找$id
$key = array_search($id,array_column($users,'id'));
//根据键名返回指定的用户信息
echo json_encode($users[$key]);
完整代码的输出:
页面上一个value值为ajax-get的按钮,点击后,向后端传递id=2,后面在users数据中搜索id=2的数据,打到后返回正文显示:灭绝(mj@php.cn)
1.2 post请求
通常用于提交表单数据,前端html与后端php在同一个目录文件
FormData是表单数据构造器
(1)append(name,value):添加表单数据
(2)delete(name):删除表单数据
示范代码:
前端:
<div class="login">
<h3>用户登录</h3>
<form action="" onsubmit="return false">
<label for="email">邮箱:</label>
<input type="email" name="email" id="email" />
<label for="password">密码:</label>
<input type="password" name="password" id="password" />
<button>提交</button>
<span class="tips"></span>
</form>
</div>
//将script脚本写在前端页面里
//获取表单数据
<script>
const form = document.querySelector(".login form");
const btn = document.querySelector(".login button");
const tips = document.querySelector(".tips");
btn.onclick = () => {
//严格按照xhr对象的四个步骤走
//1 创建xhr对象
const xhr = new XMLHttpRequest();
//2 配置xhr参数,open(type:访问方式,url:访问目标地址),以post方式,访问后端test2.php
xhr.open("post","test2.php");
//3 处理xhr响应:
//成功
xhr.onload = () => (tips.innerHTML = xhr.response);
//4 发送xhr请求,需以表单的形式发送
xhr.send(new FormData(form));
</script>
后端代码:
//使用二维数组模拟用户数据表信息
$users = [
['id'=>1, 'name'=>'天蓬','email'=>'tp@php.cn','password' => md5('123456')],
['id'=>2, 'name'=>'灭绝','email'=>'mj@php.cn','password' => md5('abc123')],
['id'=>3, 'name'=>'西门','email'=>'xm@php.cn','password' => md5('abc888')],
];
//将通过post获取的数据保存到临时变量中
$email = $_POST['email'];
$password = md5($_POST['password']);
//使用数组过滤中器查询是否存在指定的用户并返回结果
//php中function ($user) use ($email,$password)是php中匿名函数闭包的写法,匿名函数需要使用到外部变量
$res = array_filter($users,function($user) user ($email,$password){
return $user['email'] === $email && $user['password'] === $password;
});
//将结果作为请求响应返回前端
echo count($res) ===1 ? '验证成功' : '验证失败';
完整代码的输出:
页面上有一个表单输入框,提交后,下方提示输入内容,只有输出的邮箱和密码同时正确时,页面才会提示验证成功或者验证失败
1.3 跨域get请求
代码前准备:
创建两个服务器hello和world,前者存放前端代码,后者存放后端代码,个人用的是phpstudy。
前端服务器hello的前端代码:
<button>ajax-get-cors</button>
<p></p>
<script>
//获取按钮对象
const btn = document.querySelector("button");
btn.onclick = () => {
//1 创建xhr对象
const xhr = new XMLHttpRequest();
//2 配置xhr参数
xhr.open("get","http://world.io/cors1.php");
//3 处理xhr响应
xhr.onload = () => {
document.querySelector("p").innerHTML = xhr.response;
};
//4 发送xhr请求
xhr.send(null);
};
</script>
后端服务器world的cors1.php处理代码:
// 浏览器默认关闭跨域访问,故需要在服务器端开启跨域许可
// header('Access-Control-Allow-Origin: http://hello.io');
// *: 任何来源
header('Access-Control-Allow-Origin: *');
echo 'CORS:跨域请求成功';
最终输出:页面上有一个ajax-get-cors的按钮,点击后,下方显示CORS:跨域请求成功
1.4 跨域post请求
前端服务器hello的页面代码:
<button>ajax-post-cors</button>
<p class="tips"></p>
<script>
//获取按钮对象
const btn = document.querySelector("button");
const tips = document.querySelector(".tips");
btn.onclick = () => {
//1 创建xhr对象
const xhr = new XMLHttpRequest();
//2 配置xhr参数,opst方式访问cors2.php xhr.open("post","http://world.io/cors2.php");
//3 处理xhr响应
xhr.onload = () => (tips.innerHTML = xhr.response);
//4 发送xhr请求
let formData = new FormData();
formData.append("email","admin@php.cn");
formData.append("password","123456");
xhr.send(formData);
};
</script>
后端服务器world的cors2.php代码:
header('Access-Control-Allow-Origin:*');
//返回前端Post提交的数据
print_r($_POST);
最终输出结果:前端页面上有个按钮”ajax-post-cors”,点击后页面提示:Array ( [email] => admin@php.cn [password] => 123456 )
表示跨域访问成功。
2 json
json是一种语法,用来序列化其它语言创建的数据类型
json独立于任何编程语言,几乎所有编程语言都提供了访问json数据的API接口
仅支持6种数据类型:对象、数组、数值、字符串、布尔值、null
json只是借用了JS中的一些数据表示语法,与js并无关系
注:json不支持undefined。因为除了js外,其他语言没有这个词
//json提供了两个方法:
//json.stringigy(data,replacer,space) :将JS对象,序列化为json字符串,下面代码会分别介绍三个参数的作用
//json.parse():将json字符串,解析为js对象
console.log(JSON.stringify(3.14),typeof JSON.stringify(3.14)); //输出3.14 string
console.log(JSON.stringify("php.cn"),typeof JSON.stringify("php.cn")); //输出"php.cn" string
console.log(JSON.stringify(true),typeof JSON.stringify(true)); //输出true string
console.log(JSON.stringify(null),typeof JSON.stringify(null)); //输出null string
console.log(JSON.stringify([1,2,3]),typeof JSON.stringify([1,2,3])); //输出[1,2,3] string
console.log(JSON.stringify({x:"a",y:"b"}),typeof JSON.stringify({x:"a",y:"b"})); //输出{"x":"a","y":"b"} string
//json其实不是数据类型,只是一个具有特殊格式的字符串而已
//对json格式字符串的特殊操作,主要通过后面二个参数
//第二个参数支持数组 和 函数
//数组
console.log(JSON.stringify({x:"a",y:"b",z:"c"})); //输出{"x":"a","y":"b","z":"c"}
console.log(JSON.stringify({x:"a",y:"b",z:"c"},[x,y])); //输出{"x":"a","y":"b"}
//函数
console.log(JSON.stringify({a:1,b:2,c:3},(k,v) =>{
//将需要过滤的数据直接返回undefined
if(v<2) return undefined;
//过滤掉值小于2的数据,即a:1,过滤之后,返回其它 >=2 的数据
return v;
}));
//第三个参数,用来格式化输出json字符串
console.log(JSON.stringify({a:1,b:2,c:3},null,2));//前面输出两个空格
//输出:
//{
// "a":1,
// "b":2,
// "c":3
//}
3 常用数组函数
let arr = [1,2,3];
//1 类似栈的方法
arr.push(4,5);//进栈,返回5,修改后的数组长度
arr.pop();//出栈,返回5,数组中索引最大的值,即最后进入数组的值
//2 类似队列的方法
arr.shift();//出队,返回1,即数组中第一项
arr.unshift(4,5);//入队,返回修改后的数组长度
// shift结合push,unshift结合pop可以实现像队列一样操作数组
//3 join():与字符串split()相反,将数组转化为字符串返回
let arr =["电脑","手机","相册"];
console.log(arr.join());//返回:电脑,手机,相册
console.log(arr.join("*"));//返回
//4 concat()数组合并
console.log([1,2,3].concat([4,5],[6,7 ]));//输出:[1,2,3,4,5,6,7]
console.log([1,2,3].concat(123,["php",true],{x:1,y:2 }));//输出:[1,2,3,123,"php",true,{x:1,y:2}]
//5 slice():返回数组中的成员
arr = [1,2,3,4,5];
let res = arr.slice(2,4);//返回 [3,4],即索引为2和3的值,如果只写一个,就直接取到原来数组末位。
//6 splice(开始索引,删除的数量,插入的数据):数组的增删改操作,本质工作是删除数组元素,返回被删除的元素
arr = [1,2,3,4,5];
console.log(arr.splice(2));//如果只有一个参数,即是删除索引从2开始,后面所有的元素,返回值[3,4,5],此时arr:[1,2]
arr = [1,2,3,4,5];
console.log(arr.splice(2,2));//如果有两个参数,即是说明了删除的数量,返回[3,4],此时arr:[1,2,5]
arr = [1,2,3,4,5];
console.log(arr.splice(2,2,88,99));//三个或者三个以上,返回值依然是删除的元素[3,4],但插入了新的元素,arr:[1,2,88,99,5],
//以上语句也可以写成 console.log(arr.splice(2,2,...[88,99])); 不能没有...
//7 排序
arr = ["a","c","b"];
console.log(arr.sort());//按照字母的排列顺序,输出["a","b","c"]
//如果数组元素是数字,排列是先转成字符串,然后按照左侧开始每一位的数字的顺序
arr = [10,9,22,4];
console.log(arr.sort());//输出:[10,22,4,9],因为左侧开始的第一位分别是1,2,4,9
arr.sort((a,b) => a-b);//升序排列,如果后面改成b-a,就是降序排列
console.log(arr);//此时arr就是按照升序排列
//8 遍历map
arr = [1,2,3,4,5];
console.log(arr.foreach(item => console.log(item))); //逐行输出1,2,3,4,5,该没有返回值,如果我们需要赋值给某个变量,就不太方便
let res = arr.map(item => item); //此时res就是遍历arr数组后得到的数组,由于map里面是item => item,所以res 和arr是两个一模一样的数组,但如果item => item*2,则res里面每个元素都是arr对应元素的两倍
//9 过滤filter()
arr = [1,2,3,4,5];
console.log(arr.filter(item => item % 2));//item%2 为真,即item%2不为0,即是奇数
//10 归内reduce(callback(prev,curr),base)
arr = [1,2,3,4,5];
console.log(arr.reduce((prev,curr) => {
//逐行输出:1 2
// 3 3
// 6 4
// 10 5
console.log(prev,curr);
return prev+curr;
}); //最终输出 15 (数组求和)
console.log(arr.reduce((prev,curr) => {
return prev*curr;
},2)); //最终返回值240,计算过程是:基础值2*1*2*3*4*5