js急速入门之五(数组常用方法 json知识 ajax请求)
数组常用方法
- 栈方法
栈:后进先出
队:先进先出
他们是访问受限,仅允许在一端进行增删的数组
push():从数组的尾部增加成员
pop():从数组的尾部进行移除成员
unshift():从数组的头部增加成员
shift():从数组的头部移除成员
push(),shift() 模拟队 尾部进入,头部出去
unshift(),pop() 模拟队列,头部进入,尾部出去
- 栈方法
- join():与字符串的split()相反,将数组转为字符串返回
arr = ["电脑","手机","相机"];
let res = arr.join(",");
console.log(res);
//js中,字符串可以当数组使用,
let str = "hello";
console.log(str[0],str[1],str[2]);
//join()经常格式化字符串
- concat() 数组合并
在字符串中,用于字符串拼接
- concat() 数组合并
console.log("hello".concat(" php.cn"));
console.log([1,2,3].concat([4,5,6],[7,8,9]));
console.log([1,2,3].concat(123,"php",true,{x:1,y:2},["a","b"]));
注意:一维数组才有效
- slice(开始取值的索引):返回数组中的部分成员
创建数组副本
- slice(开始取值的索引):返回数组中的部分成员
arr = [1,2,3,4,5];
res = arr.slice(0);
console.log(arr.slice(3));
//返回[4,5]
// 也支持负数
console.log(arr.slice(-2));
//返回[4,5]
- splice(开始索引,删除的数量,插入的数据…):数组的增删,它的本职工作是删除元素
arr = [1, 2, 3, 4, 5];
// 5.1 删除
res = arr.splice(2);
// 返回被删除的元素
console.log(res);
//返回[3, 4, 5]
console.log(arr);
//返回[1, 2]
arr = [6, 7, 8, 9];
res = arr.splice(2, 3, 100, 200, 300);
//数组插入任然是数组
// res = arr.splice(2,3,[100,200,300]);
//可以使用...rest语法展开数组
// res = arr.splice(2,3,...[100,200,300]);
console.log(res);
//返回 [8, 9] 因为数组长度不够,后面的100,200,300并不是删除的部分
console.log(arr);
//返回[6, 7, 100, 200, 300] 原数组被替换了,多出来的300也作为成员被添加
//将第二个参数设置为0 表示,删除数量为0,不删除。第三个及以后的参数就是新增的成员
res = arr.splice(1, 0, ...[88, 99]);
console.log(res);
//返回[]空数组,因为没有要删除的成员
console.log(arr);
// 返回:[6, 88,99,7, 100, 200, 300]
注意:第一,有返回值,返回的是数组,并且是被删除的那部分成员
第二,原数组产生变化。替换的成员多就是添加,少就是删除。
- 排序
arr = ["a", "b", "c", 11, 22, 12, 23];
// 默认按字符顺序排列
console.log(arr);
arr.sort();
console.log(arr);
// 怎么才能按数字排序呢?
arr = [11, 22, 12, 23];
//升序 参与运算的时,自动转为数值
// arr.sort((a,b)=>a-b);
// 降序
arr.sort((a, b) => b - a);
console.log(arr);
- 遍历 map
返回数组
- 遍历 map
arr = [1, 2, 3, 4, 5];
console.log(arr);
// forEach()没有返回值
// arr.forEach(item => console.log(item));
// map()对数组每个成员都调用回调进行处理并返回这个数组
// res = arr.map(item => item);
res = arr.map((item) => item * 2);
console.log(res);
//返回 [2, 4, 6, 8, 10]
- 过滤
arr = [1, 2, 3, 4, 5];
console.log(arr);
// 取奇数(取余,所以得到的是奇数)
// res = arr.filter(item=>item %2);
// 取反则取得是偶数
res = arr.filter((item) => !(item % 2));
console.log(res);
//返回 [2, 4]
- 归内 reduce(回调函数(上一个值,当前值),累加初始值)
reduce(callback(prev,cur),0)
- 归内 reduce(回调函数(上一个值,当前值),累加初始值)
arr = [1, 2, 3, 4, 5];
res = arr.reduce((prev, cur) => prev + cur);
console.log(res);
//返回 15
//第二个参数是累加的初始值
res = arr.reduce((prev, cur) => prev + cur, 50);
console.log(res);
// 返回 65
json知识
// `JSON.stringify(data,replace,space)`:将js数据转为json
console.log(JSON.stringify(3.14), typeof JSON.stringify(3.14));
// 3.14 string json中数值时 string,外面不用写双引号
console.log(JSON.stringify("php"), typeof JSON.stringify("php"));
//"php" string json中字符串是 string ,外面需要用双引号
console.log(JSON.stringify(true), typeof JSON.stringify(true));
//true string json中boolean 是string,外面没有双引号
console.log(JSON.stringify(null), typeof JSON.stringify(null));
// null string json中null是string,外面也没有双引号
//array, object
// json对象的属性必须加双引号,字符串也必须加双引号,最后一个没有逗号
console.log(
JSON.stringify({ x: "a", y: "b" }),
typeof JSON.stringify({ x: "a", y: "b" })
);
console.log(
JSON.stringify([1, 2, 3, "a"]),
typeof JSON.stringify([1, 2, 3, "a"])
);
//数组和对象:object
// json 其实不是数据类型,只是一个具有特殊格式的字符串而已
// 会对json格式字符串的特殊操作,主要通过后面的第二个参数
// 第二个参数支持数组 和 函数
// 第三个参数用来格式化输出json字符串
// 数组
console.log(JSON.stringify({ 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({ x: 1, y: 2, z: 3 }, (k, v) => {
//将需要过滤掉的数据直接返回undefined
if (v < 2) return undefined;
return v;
})
);
// 返回 {"y":2,"z":3}
console.log(JSON.stringify({ x: 1, y: 2, z: 3 }, null, 2));
//返回
//{
// "x": 1,
// "y": 2,
// "z": 3
//}
console.log(JSON.stringify({ x: 1, y: 2, z: 3 }, null, "***"));
//返回
//{
//***"x": 1,
//***"y": 2,
//***"z": 3
//}
//2. JSON.parse(str,reviver),将json转为js对象,
//第二个参数可以对json的数据进行处理后再返回,
let obj = JSON.parse(`{"x": 1,"y": 2,"z": 3}`);
console.log(obj, typeof obj);
console.log(obj.x, obj.y, obj.z);
obj = JSON.parse(`{"x": 1,"y": 2,"z": 3}`, (k, v) => {
//json对象是由内向外解析
if (k === "") return v;
return v * 2;
});
console.log(obj);
//{x: 2, y: 4, z: 6}
ajax 操作
使用 phpstudy 作为虚拟服务器
配置启动apache
由于端口80被占用所以换了8088作为端口
创建两个网站:
hello.io
- test1.php
- test2.php
world.io
- cors1.php
- cors2.php
- cors3.php
XMLHttpRequest
对象
1. 配置本地服务器
2. XMLHttpRequest
是浏览器对象,而非 JS 内置对象
2.1 xhr 请求步骤
- 创建 xhr 对象:
const xhr = new XMLHttpRequest()
- 配置 xhr 参数:
xhr.open(type, url)
- 处理 xhr 响应:
xhr.onload = (...) => {...}
- 发送 xhr 请求:
xhr.send(...)
2.2. xhr 对象常用属性
序号 | 方法 | 描述 |
---|---|---|
1 | responseType |
设置响应类型 |
2 | response |
响应正文 |
2.3 xhr 对象常用方法
序号 | 方法 | 描述 |
---|---|---|
1 | open(type,url) |
配置请求参数 |
2 | send(data/null) |
发送请求 |
2.4. xhr 对象常用事件
序号 | 事件 | 描述 |
---|---|---|
1 | load() |
请求成功 |
2 | error() |
请求失败 |
ajax-get
<button>ajax-get</button>
<p></p>
<script>
const btn = document.querySelector("button");
btn.onclick = ()=>{
// 1. 创建 xhr 对象
const xhr = new XMLHttpRequest();
// 2. 配置 xhr 参数
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>
服务器端 test1.php 文件
<?php
// 以二维数组模拟数据表信息
$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,并返回对应的键名
$key = array_search($id,array_column($users,'id'));
// 根据键名返回指定的用户信息
echo json_encode($users[$key]);
ajax-post
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ajax-post</title>
<style>
#login {
width: 20em;
border: 1px solid #888;
box-sizing: border-box;
padding: 1em 2em 1em;
margin: 2em auto;
background-color: lightcyan;
display: grid;
grid-template-columns: 3em 1fr;
gap: 1em 0;
}
#login .title {
grid-area: auto / span 2;
place-self: center;
}
#login button {
grid-area: auto / 2 / auto;
}
.tips{
grid-area: auto / 2 ;
}
</style>
</head>
<body>
<form id="login" action="" method="POST">
<label class="title">用户登录</label>
<label for="email" >邮箱:</label>
<input type="email" name="email" />
<label for="password">密码:</label>
<input type="password" name="password" />
<button name="submit">登录</button>
<span class="tips"></span>
</form>
<script>
const form = document.querySelector("#login");
const btn = document.querySelector("#login button");
const tips = document.querySelector(".tips");
// let data = new FormData();
// data.append("email",form.email.value);
// data.append("password",form.password.value);
// console.log(data.get("email"),data.get("password"));
btn.onclick = (ev) => {
ev.preventDefault();
// 1. 创建 xhr 对象
const xhr = new XMLHttpRequest();
// 2. 配置 xhr 参数
xhr.open("post", "test2.php");
// xhr.responseType = "json";
// 3. 处理 xhr 响应:
//成功
xhr.onload = () => (tips.innerHTML = xhr.response);
//失败
// xhr.onerror = () => console.log("Error");
// 4. 发送 xhr 请求:
xhr.send(new FormData(form));
};
</script>
</body>
</html>
服务器端 test2.php
<?php
// print_r($_POST);
// 使用二维数组模拟用户数据表信息
$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']);
// 使用数组过滤器查询是否存在指定的用户并返回结果
$res = array_filter($users,function($user) use ($email,$password){
return $user['email'] === $email && $user['password'] === $password;
});
// 将结果做为请求响应返回到前端
echo count($res) === 1 ? '验证成功' : '验证失败';
跨域请求:ajax-get-cors
<button>ajax-get-cors</button>
<p></p>
<script>
// cors:跨域资源共享
// 同源策略: 为了请求的安全,浏览器禁止通过脚本发起一个跨域的请求
// 只允许通过脚本发起基于同源的请求
// 同源是指:协议相同,域名/主机名相同,端口相同
// http,https 协议不同,不同源
const btn = document.querySelector("button");
btn.onclick = (ev) => {
// 1. 创建 xhr 对象
const xhr = new XMLHttpRequest();
// 2. 配置 xhr 参数
xhr.open("get", "http://world.io:8088/cors1.php");
//xhr.responseType = "json";
// 3. 处理 xhr 响应:
//成功
xhr.onload = () => (document.querySelector("p").innerHTML = xhr.response);
//失败
xhr.onerror = () => console.log("Error");
// 4. 发送 xhr 请求:
xhr.send(null);
};
</script>
服务器端cors1.php 文件
<?php
//在服务器端开启跨域许可
header('Access-Control-Allow-Origin: http://hello.io:8088');
// *:任何来源都允许访问
// header('Access-Control-Allow-Origin: *');
echo 'CORS: 跨域请求成功';
跨域请求:ajax-post-cors
<button>ajax-post-cors</button>
<p class="tips"></p>
<script>
// post 也可以跨域
const btn = document.querySelector("button");
const tips = document.querySelector(".tips");
btn.onclick = (ev) => {
// 1. 创建 xhr 对象
const xhr = new XMLHttpRequest();
// 2. 配置 xhr 参数
xhr.open("post", "http://world.io:8088/cors2.php");
// 3. 处理 xhr 响应:
//成功
xhr.onload = () => (tips.innerHTML = xhr.response);
//失败
//xhr.onerror = () => console.log("Error");
// 4. 发送 xhr 请求:
let formData = new FormData();
formData.append("email","admiin@php.cn");
formData.append("password","123456");
xhr.send(formData);
};
</script>
服务器端 cors2.php
<?php
//在服务器端开启跨域许可
header('Access-Control-Allow-Origin: http://hello.io:8088');
// *:任何来源都允许访问
// header('Access-Control-Allow-Origin: *');
print_r($_POST);
jsonp
<button>jsonp-cors</button>
<p></p>
<script>
// jsonp: JSON with padding (将json填充进来)
// jsonp: 读作:json padding,别读: json 屁
// jsonp 看上去与 json 很像,是的
// jsonp:只是将json数据包含在一个函数调用中
// jsonp:callback({"id":1,"name":"admin"});
// jsonp:包括两部分:回调函数 + json数组
// 回调函数:请求接收到响应时回调的函数,可动态设置
// 回调参数:做为参数传递能函数的json数据
// jsonp 巧妙的利用了script标签发起的请求不受跨域限制的特征
// 将跨域请求的URL作为script的src属性值,实现不需要服务器授权的跨域请求
// jsonp 只能完成get请求
//---------------
// 1. jsonp原理
function getUser(data){
console.log(data);
let user=data.name+":"+data.email;
document.querySelector("p").innerHTML = user;
}
// getUser({"name":"tp","email":"tp@php.nc"});
// 将这个json从服务器上获取
// 从前端将这个需要调用的函数名称告诉服务器上的php,让php动态生成一个函数调用语句并返回
// 从服务器返回函数调用语句:`getUser({"name":"tp","email":"tp@php.nc"});`
const btn = document.querySelector("button");
btn.onclick = ()=>{
//1. 动态生成一个允许跨域请求的html元素
let script = document.createElement("script");
//2. 将跨域请求的url添加到src属性中
script.src = "http://world.io:8088/cors3.php?callback=getUser";
//3. 将script挂载到页面中
document.body.insertBefore(script,document.body.firstElementChild);
}
</script>
服务器端 cors3.php
<?php
//jsonp 不需要授权给前端
//只要返回一个使用json作为参数的函数调用语句就可以
//将前端需要的数据以json格式放到这个函数的参数中
//必须要知道前端js调用的函数名
$callback = $_GET['callback'];
//服务器中需要返回的数据
$data = '{"name":"tp","email":"tp@php.nc"}';
$data = '{"name":"MJ","email":"MJ@php.nc"}';
// getUser({"name":"tp","email":"tp@php.nc"});
echo $callback . "(" . $data. ")";
总结:ajax重中之重。