JavaScript学习笔记(五)---cookie、Proxy、服务器、PHP语言、http协议、同步异步、事件轮循机制、ajax编写、接口

  • 1.cookie
    • 1.1cookie概念
    • 1.2cookie读写
    • 1.3页面传递数据案例
    • 1.4cookie的生命周期
    • 1.5cookie的删除
    • 1.6cookie的封装
    • 1.7七天免登录
  • 2.本地及会话存储
    • 2.1localStorage和sessioonStorage都具有相同的操作方法,都是单例模式
  • 3.object.defineproperty
    • 3.1defineProperty作用
    • 3.2vue2双向绑定原理
  • 4.Proxy
  • 5.hanOwnProperty
  • 6.服务器
  • 7.PHP语言
  • 8.PHP接收前端的数据
  • 9.http协议
  • 10.ajax概念及作用
  • 11.同步和异步
  • 12.事件轮循机制
    • 12.1事件循环
    • 12.2任务队列
    • 12.3任务
    • 12.4执行顺序
  • 13.ajax编写步骤
    • 13.1ajaxGet
    • 13.2ajax对象属性
    • 13.3ajaxPost
    • 13.4php返回json
  • 14.ajax关注并加载案例
  • 15.接口
  • 16.ajax封装
  • 17.promise
    • 17.1promise案例
  • 18.async和awite
  • 19.跨域访问
  • 20.真百度搜索框

1.cookie

1.1cookie概念

  1. cookie是一个可以在页面间共享传递数据的变量。

cookie称为会话跟踪技术

会话session:一个网页APP从打开到完全关闭的过程,称为一次会话

cookie在会话期间可以在页面间共享传递数据

2.实现长生命周期的保存用户信息,实现免登录

1.2cookie读写

写:document.cookie="键=值";

读:console.log(document.cookie);

注意事项:cookie的使用必须有服务器

 // 写// document.cookie = "键=值";// document.cookie = "name=翻翻";document.cookie = "age=18";document.cookie = "name=峰峰";document.cookie = "gender=M";// 读// 通过分号和空格分开的字符串//age=18; name=峰峰; gender=Mconsole.log(document.cookie);// 实现字符串解析,获取每个key后面对应的valuelet strCookie = document.cookie;let arrCookie = strCookie.split(";");//["age=18","name=峰峰","gender=M"]for (let i = 0; i < arrCookie.length; i++) {let item = arrCookie[i].split("=");console.log("key:" + item[0], "value:" + item[1]);}

1.3页面传递数据案例

<body><button>点击</button>
</body></html>
<script>let oBtn = document.querySelector("button");oBtn.onclick = function () {document.cookie = "name=翻翻";document.cookie = "age=32";location.href = "4.cookie页面传递数据02.html";}
</script>
<script>console.log(document.cookie);
</script>

1.4cookie的生命周期

会话级别:document.cookie = "键 = 值";

长生命周期:document.cookie = "name=laowang;expires="+date;

<script>// 会话级别// document.cookie = "键=值";document.cookie = "key1=value1";// 长生命周期let date = new Date();date.setDate(date.getDate() + 10);document.cookie = "name=laowang;expires="+date;
</script>

1.5cookie的删除

cookie没有正面删除,只能侧面删除

1.将key对应的value设置为’ ’

2.将expires设置为-1(将长生命周期的cookie过期)

合起来一起用

document.cookie = "name='';expires=-1";

<script>// cookie没有正面删除,只能侧面删除// a.将key对应的value设置为''// b.将expires设置为-1(将长生命周期的cookie过期)// 合起来一起用// document.cookie = "name='';expires=-1";
</script>

1.6cookie的封装

<script>// 增改function setCookie(key, value, day) {if (day == undefined) {document.cookie = `${key}=${value}`;} else {let date = new Date();date.setDate(date.getDate() + day);console.log(date);document.cookie = `${key}=${value};expires=${date}`;}}setCookie("name", "laowang");//会话setCookie("age", 18, 7);// 查// function getCookie(key) {let strCookie = document.cookie;let arrCookie = strCookie.split(";");for (let i = 0; i < arrCookie.length; i++) {let item = arrCookie[i].split("=");if (item[0] == key) {return item[1];}}return '';}// console.log(getCookie("name"));// 删  针对长生命周期function deleteCookie(key) {setCookie(key, '', -1);}deleteCookie("age");
</script>

1.7七天免登录

主页

<body>用户名:<input type="text"><br />密码:<input type="password"><br /><select name="" id=""><option value="0">无需免登录</option><option value="7">7天免登录</option><option value="30">30天免登录</option></select><button>登录</button>
</body></html>
<script src="cookie.js"></script>
<script>if (getCookie("id") != '' && getCookie("pwd") != '') {location.href = 'ok.html';} else {// 获取输入框let oInput = document.getElementsByTagName("input");// 获取下拉框的值let oSelect = document.querySelector("select");// 获取点击按钮let oBtn = document.querySelector("button");switch (oSelect.value) {case '0':break;case '7':case '30':setCookie("id", oInput[0].value.oSelect.value / 1);setCookie("pwd", oInput[0].value.oSelect.value / 1);break;}location.href = "ok.html";}
</script>

跳转后的页面

<body>登陆成功!
</body>

封装的cookie

// 增改
function setCookie(key, value, day) {if (day == undefined) {document.cookie = `${key}=${value}`;} else {let date = new Date();date.setDate(date.getDate() + day);document.cookie = `${key}=${value};expires=${date}`;}
}// 查
function getCookie(key) {let strCookie = document.cookie;let arrCookie = strCookie.split("; ");for (let i = 0; i < arrCookie.length; i++) {let item = arrCookie[i].split("=");if (item[0] == key) {return item[1];}}return '';
}// 删  针对于长生命周期
function deleteCookie(key) {setCookie(key, '', -1);
}

2.本地及会话存储

localStorage和sessionStorage功能早期的web中使用cookies在客户端保存诸如用户名等简单的信息,但是在使用cookies存储永久数据存在以下问题:

  1. cookies的大小限制在4kB,不适合大量的数据存储。
  2. 浏览器还限制站点可以在用户计算机上存储cookies的数量。
  3. cookies是随http事务一起被发送的,因此会浪费一部分宽带。
  4. cookies的原生API贼难用。HTML5很好的提供了本地存储的功能,以键值对存储的解决方案,支持容量至少为4M~5M,HTML5的web提供了两种客户端存储方法。

localStorage:是一种没有时间限制的数据存储方式,可以将数据永久保存在客户端。

sessionStorage:指的是针对一个session的数据存储,即将数据保存在session对象中,当关闭浏览器后,这些数据就被删除。因此,sessionSetorage不是一种持久化的本地存储,仅仅是会话级别的存储。

2.1localStorage和sessioonStorage都具有相同的操作方法,都是单例模式

getItem(key):获取指定key所存储的value值

key(index)方法:返回列表中对应索引的key值

length属性:返回key/value队列的长度

removeItem(key)方法:从Storage中删除一个对应的键值对。

setItem(key,value)方法:将value存储到key指定的字段。

clear()方法:移除所有的内容

// 增改// a.setItem("key","value")localStorage.setItem("name", "老王");// sessionStorage.setItem("age", 18);// b.点运算符// localStorage.age = 18;// c.下标法localStorage["gender"] = "M";localStorage.setItem("name", "凡凡")// 查// a.getItem("key"):返回key对应的valueconsole.log(localStorage.getItem("name"));// b.点运算符console.log(localStorage.age);// c.下标法console.log(localStorage["gender"]);// 删// removeItem("key"):删除key对应的valuelocalStorage.removeItem("name");localStorage.removeItem("age");localStorage.clear();
// key(index)方法:返回列表中对应索引的key值// length属性:返回key/value队列的长度for(let i = 0 ; i<localStorage.length;i++){console.log(localStorage.getItem(localStorage.key(i)));}

可以存储数组或者对象

localStorage.setItem("data", '{"name":"老王","age":18}');// 将字符串转为JSON对象console.log(localStorage.data);let json = JSON.parse(localStorage.getItem("data"));console.log(json.name,json.age);

页面关闭时触发:

// 页面关闭时触发,window.onbeforeunload = function () {localStorage.setItem("GoodsInfor", '{"goodsName"="苹果","goodsNum":9}');}console.log(localStorage.getItem("GoodsInfor"));

3.object.defineproperty

vue2双向绑定原理

通常创建一个对象的方法

let json = {"name": "老王","age": 18}delete json.name;for(let index in json){console.log(index);}console.log(json.name,json.age);

3.1defineProperty作用

defineProperty作用:就是直接在一个对象上定义一个新属性,或者修改删除一个已经存在的属性,

通过Object.defineProperty( )定义属性,通过描述符的设置可以进行更精准的控制对象属性。

语法:Object.defineProperty (目标对象,属性名,属性描述符对象)

基础属性描述符

  • value: 18,//属性的名字
  • configurable: true,//该属性是否可以被delete删除
  • enumerable: true,//该属性是否可以被forin遍历出来
  • writable: true//该属性是否可以被修改
 let stu = {"name": "老王"}stu.age = 18;Object.defineProperty(stu, "age", {// 基础属性描述符value: 18,//属性的名字configurable: true,//该属性是否可以被delete删除enumerable: true,//该属性是否可以被forin遍历出来writable: true//该属性是否可以被修改});delete stu.age;stu.age = 999;console.log(stu.age);for(let index in stu){console.log(index);}

除了以上基础描述符外,最重要的两个描述符函数get和set

// 除了以上基础描述符外,最重要的两个描述符函数get和setlet stu = {"name": "老王","age": 18}// 时间点:当对象进行读写操作时,可以被Object.defineProperty拦截,// 也就是说,在读写的过程中,要经过Object.defineProperty检测Object.defineProperty(stu, 'name', {// 为什么属性名需要加_,为了避免递归set: function (v) {console.log("haha");// 很复杂的代码块if (v > 10) {this._name = v;} else {this._name = "数据不正确";}},get: function () {console.log("hiehie");return this._name;}})// 注意事项:在使用get和set修饰符时,不要和基础修饰符连用,否则会报错// 写stu.name = 5;// 读console.log(stu.name);

3.2vue2双向绑定原理

操作数据就等于操作dom

数据驱动思想,通过修改数据渲染页面,而不是直接操作dom

<script>// vue2双向绑定原理// 操作数据就等于操作domlet data = {"name": "老王"}let oBox = document.querySelector("#box");Object.defineProperty(data, "name", {set: function (v) {oBox.innerHTML = v;},get: function () {this._name = oBox.innerHTML;return this._name;}});data.name = "小明";console.log(data.name);// 数据驱动思想,通过修改数据渲染页面,而不是直接操作dom
</script>

4.Proxy

Vue3绑定原理,核心问题还是拦截对象属性的读写

proxy(代理)是一个对象

为什么需要代理对象?目标对象的某些功能无法实现

let p = new Proxy(目标对象,修饰符对象);

let stu = {"name": "老王",fun: function () {console.log(this);}}// 通过p对象代理stu,也就是说操作p等价于操作stulet p = new Proxy(stu, {});p.name = "嘿嘿";console.log(stu.name, p.name);// this代理对象的this问题?// 目标对象调用成员方法,this为目标对象// 代理对象调用成员方法,this为代理对象stu.fun();p.fun();

5.hanOwnProperty

用来判断某个属性是否属于自身,不去遍历原型链

let arr = [1, 2, 3];Object.prototype.a = 666;arr.b = 999;console.log(arr.a);console.log(arr.b);console.log(arr.hasOwnProperty("a"));//false,原型对象不是数组本身的元素console.log(arr.hasOwnProperty("b"));//true
 let json = {a: 1}// 原型对象只是构造函数的一个属性Object.prototype.b = 666;// 遍历的是自身及父元素原型对象的属性// for (let index in json) {//     console.log(index);//a  b// }// 只遍历自身的属性不包含继承来的属性for (let index in json) {if (json.hasOwnProperty(index)) {console.log(index);}}

6.服务器

C/S架构:客户机/服务器结构

B/S架构:浏览器/服务器结构

服务器是用来处理前后端数据交互的软件

服务器的分类:

  • web服务器:可以让用户在外网访问到自身服务器
  • 数据库服务器:存储数据的服务器

服务器有很多种:

  • web服务器,apache,nodejs,tomcat
  • 数据库服务器,mySql,oracle,sqlServer,mongodb

apache服务器是phpstudy软件自带的

apache使用方式,安装phpstudy(不能安装到桌面),启动后当apache显示绿色则服务器启动成功,我们只需要将文件放入WWW目录(开发目录的代码拷贝至部署目录),则可访问

外界就可以通过:

  • F:\htmlTest\server\WWW 等价于 ip地址
  • ip地址+文件名的方式访问

环形地址:代表本机IP的字符串或者地址

  • 127.0.0.1
  • localhost

注意事项:部署目录中不要出现中文

7.PHP语言

外文名PHP:Hypertext Preprocessor,中文名:“超文本预处理器”是一种通用开源脚本语言。语法吸收了C语言、java和Perl的特点,利于学习,使用广泛,主要适用于web开发领域。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML(标准通用标记语言下的一个应用)文档中去执行,执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执行编译后代码,编译可以达到加密和优化代码运行,使代码运行更快。

  1. 文件扩展名:php

  2. 代码写在<?php?>之间

  3. PHP代码每句话以分号结束(必须)

  4. 编码格式:

    header("Content-type:text/html;charset=utf-8");

<?php
// echo目前等价于document.write
// php除了可以做后端文件外,还能当html页面显示(通常没有人这么干)
// 支持中文
header("Content-type:text/html;charset=utf-8");
// echo "hello php";
// echo "老王";// 1.php变量的定义
// $name = "小明";
// $age = 18;
// php字符串拼接用点
// echo $name . " " . $age;// 2.if分支条件
// $a = 123;
// $b = 456;// if($a >$b){//     $c = $a ;
// }else{//     $c = $b;
// }// echo $c;// 3.数组与循环$arr = [6,5,7,4,8,3];// count数组的长度
for($i=0;$i<count($arr);$i++){echo $arr[$i]." ";
}// 4.函数
function fun($a,$b){return $a>$b?$a:$b;
}echo fun(1,2);// 注意事项:千万不要忘记分号
?>

8.PHP接收前端的数据

表单中:

  • action:数据发送的服务器文件
  • method:数据提交的方式(默认不写为get)
  • get:效率高,安全性低,将数据携带在网址后面,携带数据量小
  • post:效率低,安全性高,携带数据量大
  • name:前后端的约定

html文件:

<body><!-- action:数据发送的服务器文件method:数据提交的方式(默认不写为get)get:效率高,安全性低,将数据携带在网址后面,携带数据量小post:效率低,安全性高,携带数据量大name:前后端的约定--><form action="http://127.0.0.1:80/day27/4.login.php" method="post">ID:<input type="text" name="userName"><br>PWD:<input type="text" name="userPwd"><br><input type="submit" value="登录"></form>
</body>

PHP接收前端的数据:

* PHP接收前端的数据

* $_POST[‘参数名’]

* $_GET[“参数名”]

* $_REQUEST[“参数名”];

<?php
header("Content-type:text/html;charset=utf-8");// 接收前端数据
// * PHP接收前端的数据
// * $_POST['参数名']
// * $_GET["参数名"]
// * $_REQUEST["参数名"];  // $name = $_GET['userName'];
// $pwd = $_GET['userPwd'];$name = $_POST['userName'];
$pwd = $_POST['userPwd'];// 1.php变量的定义
$name = "小明";
$age = 18;
// php字符串拼接用点
echo $name . " " . $age;// $name = $_REQUEST['userName'];
// $pwd = $_REQUEST['userPwd'];// echo $name." ".$ped;
?>

9.http协议

http协议:基于请求和响应的超文本传输协议

如何发请求:(访问服务器文件的规则格式)

  • 完全体:http://127.0.0.1:80/day27/4.login.php

  • url地址构成

    ​ http:// ip地址 + 端口号 + 文件路径

ip地址:电脑在网络中的唯一识别符(相对于人的身份证号)

端口:标记了电脑上某一个软件的号码

如何接响应:前端只能被动接收响应数据

服务端除了响应数据外会返回一些状态码,告知前端交互情况

  • 200 数据交互成功
  • 404 你的url写错了
  • 5XX 服务器的问题,请给后端告状

10.ajax概念及作用

前言:只要发送请求,浏览器就会刷新页面,因为后端返回数据后,浏览器要重新渲染页面

需求:局部更新(异步刷新)

  • ajax(Asynchronous JavaScript And XML)技术打破了之前只要发请求就刷新页面的规则,
  • AJAX是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术
  • 前端通过与服务器进行少量数据交换,AJAX可以使网页实现异步更新。这意味着可以在不重新加载整个页面的情况下,对网页的某部分进行更新

为什么要使用AJAX

  • 更自然,流畅的用户体验,对用户的操作即时响应
  • 在不中断用户操作的情况下web服务器进行通信
  • 更灵敏的响应用户访问,实现近似于桌面应用程序的交互效果
  • 通过局部更新页面降低网络流量,提高网络的使用效率

11.同步和异步

  1. 异步代码的特点:所有的代码都需要消耗执行时间,而异步代码除了消耗执行时间外,还需要消耗等待时间
  2. 同步执行方式:代码按照顺序一步一步执行,前一步没有执行完,后一步无法执行
  3. 异步执行方式:代码在遇到需要消耗等待时间的代码时,先跳过该代码执行后续代码

异步代码的父类:和消耗时间有关的代码都是异步代码

  1. 定时器的回调函数
  2. 事件体
  3. 发请求和接响应

当同步代码与异步代码同时存在时,优先执行同步代码,在根据异步消耗的时间,执行异步代码只有同步代码遵循自上而下的执行规则,异步和消耗等待的时间有关

<script>// 1.买菜// 2.洗菜// 3.切菜// 4.烧水// 5.炒菜// 异步代码的特点:所有的代码都需要消耗执行时间,而异步代码除了消耗执行时间外,还// 需要消耗等待时间// 同步执行方式:代码按照顺序一步一步执行,前一步没有执行完,后一步无法执行// 异步执行方式:代码在遇到需要消耗等待时间的代码时,先跳过该代码执行后续代码// 异步代码的父类:和消耗时间有关的代码都是异步代码// a.定时器的回调函数// b.事件体// oBtn,onclick = function () {//     console.log("嘿嘿");//事件体是异步代码// }// c.发请求和接响应// console.log(1);// setInterval(function () {//     console.log(2);// }, 0);// setInterval(function () {//     console.log(3);// }, 0);// setInterval(function () {//     console.log(4);// }, 0);// console.log(5);// 当同步代码与异步代码同时存在时,优先执行同步代码,在根据异步消耗的时间,执行异步代码// 只有同步代码遵循自上而下的执行规则,异步和消耗等待的时间有关let time = setInterval(function () {console.log("heihei");}, 1000);// 属于同步代码clearInterval(time);
</script>

12.事件轮循机制

12.1事件循环

事件循环是什么?为什么要有事件循环这个东西?

我们都知道js是单线程的,但是像Ajax,或者是事件这种很耗时的操作,需要用并发处理,否则单线程会长时间等待,什么也做不了。而事件循环就是并发的一种形式,一个线程中只有一个事件循环。而任务队列是用来配合事件循环完成操作的,一个线程可以拥有多个任务队列

12.2任务队列

所谓任务是webAPIs返回的一个个通知,让js主线程在读取任务队列的时候得知这个异步任务已经完成,下一步该执行这个任务的回调函数了。主线程拥有多个任务队列,不同的任务队列用来排列来自不同任务源的任务。

任务源是什么?

像setTimeout/Promise/DOM 事件等都是任务源,来自同类任务源的任务我们称它们是同源的,比如setTimeout与setInterval就是同源的。 在es6标准中任务队列又分为宏观任务队列和微观任务队列

12.3任务

所有任务可以分两种:一种是同步任务(synchronous) ,另一种是异步任务(asynchronous) 。

同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;//执行栈

异步任务指的是,不先进入主线程,而进入"任务队列"(task queue) 的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。

12.4执行顺序

  1. 先执行同步代码
  2. 当异步代码结束等待状态,进入准备执行状态,通知主线程
  3. 当主线程的同步代码执行完毕时,执行异步代码
  4. 重复以上三步

13.ajax编写步骤

1.创建XMLHttpRequest对象

let xhr = new XMLHttpRequest();

2.调用open方法(规划请求)

xhr.open("get/post忽略大小写","服务器文件地址",是否异步);

3.send(真实发送请求)post的请求参数通过send发送

xhr.send([请求参数]);

4.onreadystatechange事件(异步)

onreadystatechange事件是由readyState属性发生改变而触发的,但是只有2~4的改变会触发该事件

0:刚创建完xhr对象

1:调用完OPEN方法

​ 2.请求发送出去

​ 3.请求发送到了服务器

​ 4.请求数据完成解析,可以进行响应

status:

​ // 200 代表协议顺利,数据交互完成

​ // 404 网址写错了

​ // 5xx 服务器问题

xhr.onreadystatechange = function () {// status == 200; 电话打通了,嘟嘟嘟// readyState == 4:人家接通了电话if (xhr.status == 200 && xhr.readyState == 4) {// 5.回复你响应 --->xhr.responseTextfun(xhr.responseText);}}function fun(resText) {// console.log(resText);let p = document.querySelector("p");p.innerHTML = resText;}
<body><div>哈哈哈</div><button>发送</button><p></p>
</body></html>
<script>let oBtn = document.querySelector("button");oBtn.onclick = function () {// 1.掏手机   --->  创建XMLHttpRequest对象let xhr = new XMLHttpRequest();// 2.拨号   --->  调用open方法// xhr.open(请求方式,服务器地址,true);xhr.open("get", "02.txt", true);// 3.发射   --->  sendxhr.send();// 4.等  --->  onreadystatechange事件(异步)xhr.onreadystatechange = function () {// status == 200; 电话打通了,嘟嘟嘟// readyState == 4:人家接通了电话if (xhr.status == 200 && xhr.readyState == 4) {// 5.回复你响应 --->xhr.responseTextfun(xhr.responseText);}}}function fun(resText) {// console.log(resText);let p = document.querySelector("p");p.innerHTML = resText;}</script>

13.1ajaxGet

html文件

<body><input type="text"><span></span>
</body></html>
<script>let oInput = document.querySelector("input");let oSpan = document.querySelector("span");oInput.onblur = function () {let xhr = new XMLHttpRequest();// url?key1=value1&key2=value2....// form表单和ajax都是发请求给后端,两个不能重复,等于说以前的事是浏览器干现在在是你干// userName就是form表单中input的name属性的值xhr.open("GET", "03.ajacGet.php?userName" + this.value, true);xhr.send();xhr.onreadystatechange = function () {if (xhr.status == 200 && xhr.readyState == 4) {fun(xhr.responseText);//所有的操作都是为了获取响应内容}}}function fun(resText) {oSpan.innerHTML = resText;}
</script>

php文件

<?phpheader("Content-type:text/html;charset=utf-8");$name = $_GET["userNamer"];// 模拟数据库$arr = ["峰峰","凡凡","小明","小米"];// in_array(查找的目标元素,数组);找到返回下标,没找到返回空if(in_array($name,$arr)){// php在参与ajax的过程中,echo的作用为返回响应each '用户名已经存在';}else{echo '可以注册';}
<?phpheader("Content-type:text/html;charset=utf-8");$name = $_GET["userNamer"];// 模拟数据库$arr = ["峰峰","凡凡","小明","小米"];// in_array(查找的目标元素,数组);找到返回下标,没找到返回空if(in_array($name,$arr)){// php在参与ajax的过程中,echo的作用为返回响应each '用户名已经存在';}else{echo '可以注册';}
?>

13.2ajax对象属性

<script>// 创建XMLHttpRequest对象let xhr = new XMLHttpRequest();// xhr.open("get/post忽略大小写","服务器文件地址",是否异步);console.log(xhr.readyState);// get的请求参数携带在urlxhr.open("get", "02.txt", true);console.log(xhr.readyState);// post的请求参数通过send发送// xhr.send([请求参数])xhr.send();// onreadystatechange事件是由readyState属性发生改变而触发的,但是只有2~4的改变会触发该事件// 0:刚创建完xhr对象// 1:调用完OPEN方法// 2.请求发送出去// 3.请求发送到了服务器// 4.请求数据完成解析,可以进行响应xhr.onreadystatechange = function () {// status:// 200 代表协议顺利,数据交互完成// 404 网址写错了// 5xx 服务器问题// console.log(xhr.responseText);if (xhr.readyState == 4 && xhr.status == 200) {// 接收的响应内容console.log(xhr.responseText);}}
</script>

13.3ajaxPost

与get的不同点:

1.请在open和send之间,设置请求头,将数据以form表单post形式发送

xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")

2.将请求参数通过send发送

key1=value1&key2=value2…

xhr.send(userName=${this.value});

html文件:

<!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><input type="text"><span></span>
</body></html>
<script>let oInput = document.querySelector("input");let oSpan = document.querySelector("span");oInput.onblur = function () {let xhr = new XMLHttpRequest();xhr.open("post", "05.ajaxPost.php", true);// 1.请在open和send之间,设置请求头// 将数据以form表单post形式发送xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")// 2.将请求参数通过send发送// key1=value1&key2=value2...xhr.send(`userName=${this.value}`);xhr.onreadystatechange = function () {if (xhr.status == 200 && xhr.readyState == 4) {fun(xhr.responseText);//所有的操作都是为了获取响应内容}}}function fun(resText) {// 前后端分离,// 前端主要实现页面渲染// 后端尽可能少实现描述性数据if (resText == "1") {oSpan.innerHTML = "好了";} else if (resText == "0") {oSpan.innerHTML = "不好了";}}
</script>

php文件

<?phpheader("Content-type:text/html;charset=utf-8");$name = $_POST["userName"];//模拟数据库$arr = ["凢凢","峰峰","翔翔","波波"];//in_array(查找的目标元素,数组);找到返回下标,没找到返回空if(in_array($name,$arr)){//php在参与ajax的过程中,echo的作用为返回响应// echo '用户名已经存在';echo "1";}else{// echo '可以注册';echo "0";}
?>

13.4php返回json

html文件

<!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><ul></ul>
</body></html>
<script>let xhr = new XMLHttpRequest();xhr.open("get", "06.phpReturnJson.php", true);xhr.send();xhr.onreadystatechange = function () {if (xhr.status == 200 && xhr.readyState == 4) {fun(xhr.responseText);}}function fun(resText) {// console.log(resText);let json = JSON.parse(resText);let oUl = document.querySelector("ul");for (let index in json) {oUl.innerHTML += `<li>${json[index]}</li>`;}}
</script>

php文件


<?phpheader("Content-type:text/html;charset=utf-8");//1.直接返回json字符串// echo '{"1":"美羊羊","2":"洋了个洋","3":"狗了个狗"}';//2.通过数组转换json字符串$arr = ["A"=>"喜羊羊","B"=>"洋了个洋","C"=>"狗了个狗"];//将$arr转为json字符串echo json_encode($arr);
?>

14.ajax关注并加载案例

该案例得在服务器apache下运行

html文件

<!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><div></div><button>关注并加载更多</button>
</body></html>
<script src="ajax.js"></script>
<script>let oDiv = document.querySelector("div");let oBtn = document.querySelector("button");function getNews(page) {// let xhr = new XMLHttpRequest();// xhr.open("get", "1.getNews.php?page=" + page, true);// xhr.send();// xhr.onreadystatechange = function () {//     if (xhr.readyState == 4 && xhr.status == 200) {//         fun(xhr.responseText);//     }// }ajax("1.getNews.php", "get", "page=" + page, fun);}getNews(1);oBtn.onclick = function () {getNews(2);this.style.display = "none";}function fun(resText) {console.log(resText);oDiv.innerHTML += resText;}
</script>

php文件

<?phpheader("content-type:text/html;charset=utf-8");$page = $_GET["page"];if($page == 1){echo "我感觉";}else if($page == 2){echo "还好。";}
?>

ajax封装的js文件

function ajax(url, type, data, callBack) {let xhr = new XMLHttpRequest();type = type.toLowerCase();if (type == "get") {let urlParam = url;// 有参if (data != "") {urlParam += "?" + data;}xhr.open(type, urlParam, true);xhr.send();} else {xhr.open(type, url, true);xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");// 有参if (data != "") {xhr.send(data);} else {xhr.send();}}xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {callBack(xhr.responseText);}}
}

15.接口

接口概念:后端提供的服务器文件地址,通过这些文件地址,可以发送请求获取响应内容

访问接口的四要素:

  1. 接口文件地址
  2. 发送请求方式 get/post
  3. 请求参数
  4. 响应数据内容

16.ajax封装

html文件

<!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></body></html>
<script>// url:请求地址// type:请求方式:get/post// data:请求参数:key1=value1&key2=value2  无参""// callBack:接收响应的回调函数function ajax(url, type, data, callBack) {let xhr = new XMLHttpRequest();type = type.toLowerCase();if (type == "get") {let urlParam = url;// 有参if (data != "") {urlParam += "?" + data;}xhr.open(type, urlParam, true);xhr.send();} else {xhr.open(type, url, true);xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");// 有参if (data != "") {xhr.send(data);} else {xhr.send();}}xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {callBack(xhr.responseText);}}}ajax("3.myAjax.php", "GET", "name=老王&pwd=666", fun);function fun(resText) {console.log(resText);}
</script>

php文件

<?phpheader("content-type:text/html;charset=utf-8");$name = $_REQUEST["name"];$pwd = $_REQUEST["pwd"];echo $name . " " .$pwd;
?>

17.promise

需求:当函数嵌套过多就会形成回调地狱,多级异步操作的回调函数嵌套

如何优化回调地狱?

promise概念:是一个对象,是专门用来处理异步操作的容器

promise作用:promise是处理异步操作的一种方式,通过promise可以将函数嵌套调用的方式,改为平级调用,最常用于发请求和接响应

语法规则:

let p = new Promise(function(接收响应成功的函数,[接收响应失败的函数]){

​ // 该回调函数就是包裹异步操作的容器

});

promise对象在使用的时候函数需要返回promise对象

以前的回调函数是通过promise对象的then方式传递的,promise对象.then(接收成功响应的函数,[接收失败响应的函数])

<script>// function f1(f) {//     console.log("f1");//     f();// }// function f2(f) {//     console.log("f2");//     f();// }// function f3() {//     console.log("f3");// }// f1(f3);// 这样的写法是错误的,函数f3当做函数f2的形参传入f2中调用// 而f2后面有括号可以理解为f2已经被调用了,所以f1中传入的就是// f2函数调用后的返回值,而实际上f1需要传进去的参数应该是// 一个函数,导致程序出现错误。// f1(f2(f3));// 给已经被调用的f2的外侧加一个匿名函数就可以保证传给f1的是// 一个函数// f1(function () {//     f2(f3);// })// ---------------------// function f1(f) {//     console.log("f1");//     f();// }// function f2(f) {//     console.log("f2");//     f();// }// function f3(f) {//     console.log("f3");//     f();// }// function f4() {//     console.log("f4");// }// // // 回调地狱,其实就是回调函数嵌套过多导致// f1(function () {//     f2(function () {//         f3(f4);//     });// });// 围绕着该重点理解// ajax(第一个请求,function(第一个响应)){//     ajax(第二个请求,第一个响应作为请求参数,function(第二个响应)){//         ajax(第三个请求,第二个响应作为请求参数,function(第三个响应)){//         }//     }// }// 有的就有好几个请求嵌套,第一个请求响应后的回复响应的数据要作为第二个请求响应的参数// 发生第二次请求,第二次请求响应后得到的数据要进行作为第三个请求的参数// 如何优化回调地狱?// promise概念:// promise是一个对象,是专门用来处理异步操作的容器// promise的作用:// promise是处理异步操作的一种方式,通过promise可以将函数嵌套调用的方式,改为平级调用// 最常用于发请求和接响应// let p = new Promise(function(接收响应成功的函数,[接收响应失败的函数]){//     // 该回调函数就是包裹异步操作的容器// });// function f1(f) {//不能再让回调函数通过参数传递了//     console.log("f1");//     f("成功的响应")// }// function f2(resText) {//     console.log(resText);// }// f1(f2);// ----------------------------------// function f1() {//     console.log("f1");//     let p = new Promise(function (f2) {//         f2("成功接收的响应");//     });//     return p;// }// function f2(resText) {//     console.log(resText);// }// // 以前的回调函数是通过promise对象的then方法传递的// // promise对象.then(接收成功响应的函数,[接收失败响应的函数])// f1().then(f2);function f1() {console.log("f1");let p = new Promise(function (f) {f();});return p;}function f2() {console.log("f2");let p = new Promise(function (f) {f();});return p;}function f3() {console.log("f3");let p = new Promise(function (f) {f();});return p;}function f4() {console.log("f4");}f1().then(f2).then(f3).then(f4);
</script>

17.1promise案例

场景1:异步操作过程中,比如f2发送请求需要依赖于f1的响应,f3发送请求依赖于f2的响应,

这就意味着异步代码必须以同步的方式按顺序执行,

解决方案:将f2写在f1的回调,将f3写在f2的回调,代价就是回调地狱

初步解决方案promise,可以将函数嵌套调用改为平级调用

场景2:同时发送若干请求,需要所有请求都完成响应后再渲染页面

Promise.all([请求1,请求2…]).then(resText=>{

​ });

当哪个请求失败了全部失败必须要全部完成响应

场景3:往往需要的到的响应内容,不是只有一个接口的,可以同时发送多个请求,哪个响应快用哪个

Promise.race([p1,p2,p3]).then(resText=>{

})

<script>// 场景1:异步操作过程中,比如f2发送请求需要依赖于f1的响应,f3发送请求依赖于f2的响应,// 这就意味着异步代码必须以同步的方式按顺序执行,// 解决方案:将f2写在f1的回调,将f3写在f2的回调,代价就是回调地狱// 初步解决方案promise,可以将函数嵌套调用改为平级调用// let x = f1();// let y = f2(x);// f3(y);// 场景2:同时发送若干请求,需要所有请求都完成响应后再渲染页面// Promise.all([请求1,请求2...]).then(resText=>{// });// 当哪个请求失败了全部失败必须要全部完成响应// let p1 = new Promise(function (success, failed) {//     // setInterval(function () {//     //     success("p1的响应");//     // }, 1000);//     setInterval(function () {//         failed("失败了");//     }, 1000);// });// let p2 = new Promise(function (success) {//     setInterval(function () {//         success("p2的响应");//     }, 500);// })// let p3 = new Promise(function (success) {//     setInterval(function () {//         success("p3的响应");//     }, 2000);// })// Promise.all([p1, p2, p3]).then(resText => {//     console.log(resText);// })// 场景3:// 往往需要的到的响应内容,不是只有一个接口的,可以同时发送多个请求,哪个响应快用哪个// Promise.race([p1,p2,p3]).then(resText=>{// })let p1 = new Promise(function (success, failed) {setInterval(function () {success("p1的响应");}, 1000);});let p2 = new Promise(function (success) {setInterval(function () {success("p2的响应");}, 500);})let p3 = new Promise(function (success) {setInterval(function () {success("p3的响应");}, 2000);});Promise.race([p1, p2, p3]).then(resText => {console.log(resText);});
</script>

18.async和awite

async专门用来修饰异步函数的关键字

当某个函数被async修饰时,则返回携带响应内容的Promise对象

注意事项:async wait的作用是用来等待异步方法的响应结果

并且await只能出现在async修饰的方法中

<script>// async专门用来修饰异步函数的关键字// 当某个函数被async修饰时,则返回携带响应内容的Promise对象// function f1() {//     return new Promise(function (success) {//         success("嘿嘿");//     });// }// 和上述代码的返回值相同都是Promise {<fulfilled>: undefined}// async function f1() {//     return "嘿嘿";// }// console.log(f1());// --------------------------// async function f1() {//     return "heihei";// }// // 注意事项:async wait的作用是用来等待异步方法的响应结果// // 并且await只能出现在async修饰的方法中// async function f() {//     let resText1 = await f1();//     console.log(resText1);// }// console.log(f());// 上述代码执行过程,先调用函数f()执行函数f(),函数f()中先执行await关键字后面// 的函数调用f1(),进入函数f1()并返回返回携带响应内容的Promise对象,将响应内容// 赋给resText1,打印出来。// ----------------------------// async function f1() {//     // return "heihei";//     return new Promise(function (success) {//         setTimeout(function () {//             success("嘿嘿");//         }, 1000);//     });// }// async function f() {//     let resText1 = await f1();//     console.log(resText1);// }// console.log(f());// 上述代码的执行过程:// 函数f1先被调用,执行函数f1的时候先执行await后的调用函数f1// 函数f1被调用并返回携带响应数据的Promise对象// 将携带的数据赋给变量resText1,并输出// ---------------------async function f1() {return new Promise(function (success) {setTimeout(function () {success("p1的响应");}, 1000);});}async function f2(param) {console.log(param + "哈哈");return new Promise(function (success) {setTimeout(function () {success("p2的响应");}, 500);});}async function f3(param) {console.log(param + "嘤嘤嘤");return new Promise(function (success) {setTimeout(function () {success("p3的响应");}, 2000);});}async function fun() {let resText1 = await f1();console.log(resText1);let resText2 = await f2(resText1);console.log(resText2);let resText3 = await f3(resText2);console.log(resText3);}fun();
</script>

19.跨域访问

跨域:跨域名访问,网站A页面访问网站B服务器上的文件

但是由于浏览器的安全机制同源策略,不允许跨域访问

同源策略:同IP,同协议,同端口

No ‘Access-Control-Allow-Origin’(不允许跨域访问)

前端跨域:

jsonp:是前端一种跨域的技术

如何实现跨域?

  1. src属性是可以跨域的
  2. script标签拥有src属性,可以访问远程文件
  3. 前后端约定函数名,前端写函数定义,后端写函数调用

注意事项:jsonp只支持get,所以只能通过get方式发送请求参数

后端跨域:

cors

header(“Access-Control-Allow-Origin:*”);

<body><!-- <img src="http://10.48.183.118/1.jpg" alt=""> --><img src="http://10.48.183.100/3.jpg" alt="">
</body></html>
<script>// 跨域:跨域名访问,网站A页面访问网站服务器上的文件// 但是由于浏览器的安全机制同源策略,不允许跨域访问// 同源策略:同IP,同协议,同端口let xhr = new XMLHttpRequest();xhr.open("get", 'http://10.48.183.118/2.php', true)xhr.send();xhr.onreadystatechange = function () {if (xhr.status == 200 && xhr.readyState == 4) {fun(xhr.responseText);}}function fun(resText) {console.log(resText);}// No 'Access-Control-Allow-Origin'// 不允许跨域访问// -------------------------// 前端跨越:// jsonp:是前端一种跨越的技巧// 如何实现跨域?// 1.src属性是可以跨域的// 2.script标签拥有src属性,可以访问远程文件// 3.前后端约定函数名,前端写函数定义,后端写函数调用// 注意事项:// jsonp只支持get,所以只能通过get方式发送请求参数function fun(resText) {console.log(resText);}// fun("马上十一了嘿嘿嘿");// 后端跨域:// cors// header("Access-Control-Allow-Origin:*");
</script>
<!-- <script src="http://10.48.183.118/1.txt"></script> -->
<!-- <script src="http://10.48.183.118/2.php"></script> -->

20.真百度搜索框

<body><input type="text"><ul></ul>
</body></html>
<script>// 接口四要素// 1.接口地址// http://suggestion.baidu.com/su// 2.请求方式// get// 3.请求参数// wd:搜索的关键字// cb:传递后端的函数名// 4.返回的响应内容// {//     q:"迪丽热巴",//     p:false,//     s:[//         "迪丽热巴演的电视剧",//         "迪丽热巴个人所有资料",//         "迪丽热巴男朋友",//         "迪丽热巴照片",//         "迪丽热巴微博",//         "迪丽热巴代言的品牌有哪些",//         "迪丽热巴肚子上怎么有妊娠纹",//         "迪丽热巴金主",//         "迪丽热巴身材",//         "迪丽热巴体重"//         ]// }let oInput = document.querySelector("input");let oUl = document.querySelector("ul");oInput.oninput = function () {if (this.value != "") {let oScript = document.createElement("script");document.body.appendChild(oScript);oScript.src = `http://suggestion.baidu.com/su?wd=${this.value}&cb=fun`;} else {oUl.innerHTML = "";}}function fun(resText) {oUl.innerHTML = "";for (let i = 0; i < resText.s.length; i++) {oUl.innerHTML += `<li>${resText.s[i]}</li>`;}}
</script>

JavaScript学习笔记(五)---cookie、Proxy、服务器、PHP语言、http协议、同步异步、事件轮循机制、ajax编写、接口相关推荐

  1. JavaScript学习笔记五:变量、作用域和内存问题

    1.ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值.在很多语言中,字符串以对象的形式来表示,因此被认为是引用类型的,ECMAScript放弃了这一传统. 2.从一个变量向 ...

  2. JavaScript:学习笔记(9)——Promise对象

    JavaScript:学习笔记(9)--Promise对象 引入Promise Primose是异步编程的一种解决方案,比传统的解决方案回调函数和事件更加合理和强大.如下面为基于回调函数的Ajax操作 ...

  3. JavaScript学习笔记(五)

    JavaScript学习笔记(五) ①Array类 本地对象 ②Date类 ①Global对象 对象的类型   内置对象 ②Math对象 宿主对象 今天继续学习JS中的对象,昨天内置对象Global对 ...

  4. JavaScript学习笔记(十五)

    JavaScript学习笔记(十五) 事件 事件是DOM(文档对象模型)的一部分.事件流就是事件发生顺序,这是IE和其他浏览器在事件支持上的主要差别. 一.事件流 1.冒泡型事件 IE上的解决方案就是 ...

  5. JavaScript 学习笔记(二)

    JavaScript 学习笔记(二) 文章目录 JavaScript 学习笔记(二) 一 JSON 1. JSON 对象 什么是JSON对象 JSON对象与Javascript对象的区别 在JavaS ...

  6. JavaScript学习笔记之DOM篇,带你全面了解什么是DOM

    DOM在前面的JavaScript学习笔记(一)–JS基础里简单提到过,它是浏览器厂商提供的用来控制html / css 的代码的文档对象模型,是JavaScript的重要组成部分,现在带大家详细了解 ...

  7. JavaScript学习笔记(六)--数组

    数组初始化 我们都知道,数组是用于保存多个值的集合,在数组中,值被称为元素,值可以是任意的数据类型.在Javascript中,创建数组通常有两种方式:字面量和构造函数. 字面量 数组的元素可以是任意的 ...

  8. JavaScript学习笔记(三)--操作运算符

    JavaScript中的运算符有很多,主要分为算术运算符,比较运算符,逻辑运算符,三目运算符.一元运算符.位运算符等.这些运算符都有一些属于自己的运算规则,下面就为大家介绍一下JavaScript中的 ...

  9. JavaScript学习笔记:创建、添加与删除节点

    JavaScript学习笔记:创建.添加与删除节点 文章目录 JavaScript学习笔记:创建.添加与删除节点 一.DOM对象节点类型 二.创建节点 1.创建元素节点 2.创建文本节点 3.创建属性 ...

最新文章

  1. JavaScript字符串
  2. 概率论02 概率公理
  3. ZOJ2158,POJ1789
  4. CYQ.Data 轻量数据层之路 使用篇五曲 MProc 存储过程与SQL(十六)
  5. 批量kill掉包含某个nginx的进程
  6. macos ntfs插件_Mac下NTFS读写插件NTFS for Mac介绍
  7. WPF 自动选择dll,以SQLite为例
  8. Android 7.1 App Shortcuts使用
  9. javascript widget ui mvc
  10. Python3的opencv环境搭建简易教程
  11. visualboyadvance滤镜_研究VisualBoyAdvance的请进
  12. 三菱PLC的MX_COMPONENT安装过程
  13. 机器学习的13种算法和4种学习方法,推荐给大家
  14. 德律aoi程式制作_精典德律AOI检测程式制作手册(全).ppt
  15. Word 2016封面不显示页码
  16. MySQL下载压缩包安装详细过程
  17. mac磁盘工具中磁盘显示灰色
  18. C300--HGU ONU 配置思路指导_方式1
  19. wait释放锁的说明
  20. 医学检验质量管理和控制计算机的,【临床医学论文】临床医学检验技术质量管理现状分析(共4169字)...

热门文章

  1. 表单事件(城市列表等)
  2. GIT、GITLAB、GITHUB、GITLIB
  3. 计算机网络技术的教育特性,2017年自考计算机网络技术模拟试题一
  4. SAP HANA 学习指南
  5. LQ0123 小朋友崇拜圈【DFS】
  6. 信号处理趣学D1——相关函数的意义利用自相关函数消除噪声
  7. 使用nexus-3.10x以上版本构建maven私服仓库
  8. 【Java】try里面return,finally还会执行吗?
  9. python中repr方法_(转)Python中的常见特殊方法—— repr方法
  10. 易查分如何导入数据?这个最关键的要点别忽略