AJAX

  • AJAX:(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术
  1. 异步:javascript语言是一门“单线程”的语言,javascript就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个任务和流程,无论如何,js做事情的时候都是只有一条流水线(单线程),同步和异步的差别就在于这条流水线上各个流程的执行顺序不同。
  • 区别:
    • 同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务
    • 异步任务指的是,不进入主线程、而进入"任务队列"的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。
  1. xml可扩展的标记语言,所有的标签都是自定义的,保存数据。(json更好的取代xml)
  2. ajax请求步骤
    //1.新建ajax对象
    let ajax = new XMLHttpRequest();
    //2.ajax对象的open()
    //open(请求方式get/post,接口地址,是否异步true异步/false同步)
    ajax.open('get','http://localhost/JS1909/Day%2021/5.phparray.php',true);

    //3.ajax对象的send()
    ajax.send();
    // ajax.readyState:就绪状态--0(初始化) 1(请求建立) 2(发送完成) 3(解析) 4(完成)
    // 0:请求初始化(还没有调用 open())。
    // 1:请求已经建立,但是还没有发送(还没有调用 send())。
    // 2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。
    // 3:请求在处理中;通常响应中已有部分数据可用,但是服务器还没有完成响应的生成。
    // 4:响应已完成;您可以获取并使用服务器的响应了。


    //4.ajax对象的事件--onreadystatechange监听就绪状态是否完成。
    ajax.onreadystatechange=function(){
        if(ajax.readyState===4){//请求完成
        //ajax.responseText:ajax请求返回的内容就被存放到这个属性下面,返回获取的内容,string
            console.log(ajax.responseText);
            console.log(JSON.parse(ajax.responseText));
        }
    }


    //注意:
    //异步:ajax的事件监听,可以放到open或者send上面。
    //同步:无需ajax的事件监听,可以直接在send()之后获取数据。
  1. 获取各种数据类型
    let ajax=new XMLHttpRequest();
    //ajax.open('get','http://localhost/JS1909/Day%2022/app/data.xml',true);
    //ajax.open('get','http://localhost/JS1909/Day%2022/app/data.json',true);
    //ajax.open('get','http://localhost/JS1909/Day%2022/app/data.js',true);
    ajax.open('get','http://localhost/JS1909/Day%2022/app/data.html',true);
    ajax.send();
    ajax.onreadystatechange=function(){
        if(ajax.readyState===4){
            //console.log(ajax.responseXML);//返回xml文档
            //1.xml文档
            // let xmldoc=ajax.responseXML;
            // console.log(xmldoc.querySelector('bookname').innerHTML);

            //2.json文件
            // let jsondata=ajax.responseText;
            // console.log(JSON.parse(jsondata));

            //3.js文件
            // let jsdata=ajax.responseText;
            // console.log(jsdata);

            //4.html文件
            // let htmldata=ajax.responseText;
            // console.log(htmldata);

            //5.常用的数据文件--.php .jsp .xml




        }
    }
  1. ajax局部更新
    //局部更新:通过定时器不断发送请求。
    //刷新:全局更新。
    setInterval(function () {
        let ajax = new XMLHttpRequest();
        ajax.open('get', 'http://localhost/JS1909/Day%2022/php/news.php', true);
        ajax.send();
        ajax.onreadystatechange = function () {
            if (ajax.readyState === 4) {
                console.log(ajax.responseText);
                let newsdata = JSON.parse(ajax.responseText); //数组
                let strhtml = '<ul>';
                for (let value of newsdata) {
                    strhtml += `
                    <li>
                        <a href="#">${value.title}</a><span>${value.date}</span>
                    </li>
                `;
                }
                strhtml += '</ul>';
                document.querySelector('.news').innerHTML = strhtml;
            }
        }
    }, 1000);


    //network:前后端交互最核心的信息面板。
  1. 前端发送数据
  • form+submit+name将表单的数据给后端--适合表单
    • 后端直接通过name值获取表单里面的数据
    • 设置action和method
    • action:数据提交给的页面地址
    • method:数据提交的方式,默认是get方式
  • ajax方式:表单中的某个值,非表单的数据
    • get传输数据:将数据通过?和&符号拼接在地址栏的后面
    • post传输数据:直接放到send方法里面
  1. post和get的区别
  • get:不安全,数据会暴露在地址栏,长度有限制
  • post:安全性高,通过头文件传输,长度可以自由设置
  • get和post:发送数据的方式不一样,get拼接在地址栏的后面,post通过设置请求头实现,将数据放到send里面
  1. http状态码
  • ajax.status:获取http的状态码
  • 200 OK 请求已成功,请求所希望的响应头或数据体将随此响应返回。出现此状态码是表示正常状态。
  • 304 Not Modified 文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。
  • 404 Not Found请求失败,请求所希望得到的资源未被在服务器上发现。
  • 403 Forbidden 服务器已经理解请求,但是拒绝执行它。
  • 301 Moved Permanently 被请求的资源已永久移动到新位置。
  • 302 Move Temporarily请求的资源临时从不同的 URI响应请求。
  • 501 Not Implemented 服务器不支持当前请求所需要的某个功能。
  • 502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
  • 503 Service Unavailable 由于临时的服务器维护或者过载,服务器当前无法处理请求

    容错处理

  • try...catch...finally
  • 先执行 try { ... }的代码,如果try里面的代码出错,转而执行 catch (e) { ... }代码,最后执行 finally { ... }代码
    // try{
    //     alert(a);
    // }catch(e){//e:try里面的报错信息。
    //     alert('catch');
    //     alert(e);//ReferenceError: a is not defined
    // }finally{
    //     alert('我的代码一定会触发,不管try还是catch有错');
    // }

JSON.parse和eval的区别

  1. JSON.parse():将json格式的字符串转换成对象(数组for...of和对象for...in),具有json格式检测功能
  2. eval:方法不会去检查数据是否符合json的格式,同时如果给的字符串中存在js代码eval也会一并执行,比较而言,eval方法是很危险的

跨域

  1. 跨域的报错信息
Access to XMLHttpRequest at 'http://api.k780.com/?app=weather.future&weaid=hangzhou&&appkey=43633&sign=3050bb4c62ee490c994d41b450b65ba1&format=json' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
  1. 为什么产生跨域:浏览器的同源策略
  2. 同源策略:同源策略是浏览器最核心也最基本的安全功能.
  • 同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前Web页面的域相同。同源策略是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
  1. 哪些情况会出现跨域
  • 端口不同。
  • 协议不同http/https
  • 域名和域名对应的ip地址 127.0.0.1本地ip localhost本地域名
  • 一级域名和二级域名。
  • 域名完全不同。
  1. 解决跨域
  • 后端代理
    • 后端不存在跨域,因为后端脱离浏览器。后端先获取接口的数据,传给前端
      ```
      // let ajax1 = new XMLHttpRequest();
      // ajax1.open('get','http://localhost/JS1909/Day%2023/joke.php',true);
      // ajax1.send();
      // ajax1.onreadystatechange = function () {
      // if (ajax1.readyState === 4) {
      // console.log(JSON.parse(ajax1.responseText));
      // document.body.innerHTML=JSON.parse(ajax1.responseText).content;
      // }
      // }
- cors(xhr2:xhr升级版):跨域资源共享
let ajax2 = new XMLHttpRequest();
ajax2.open('get', 'http://127.0.0.1/JS1909/Day%2022/php/taobaodata.php', true);//ip和域名跨域
ajax2.send();
ajax2.onreadystatechange = function () {
    if (ajax2.readyState === 4) {
       console.log(ajax2.responseText);
    }
}
- jsonp
  - 原理:script里面src属性 不存在跨域
  - jsonp:json with padding  json数据填充到一个函数里面
    - script里面src属性 不存在跨域。
    - jsonp请求方式采用的是get方式,回调函数。
    - jsonp:适合第三方接口的数据格式就是jsonp格式的。
#### 回调函数
1. 回调函数(高阶函数):函数做参数,传递给另外一个函数。callback
2. 为什么使用回调函数
- js代码正常情况下按照顺序执行的。回调函数解决顺序问题。(同步顺序,异步顺序)
- 函数是对象,函数可以当做参数被传递
#### promise
- Promise:是异步编程的一种解决方案,比传统的回调函数和事件要更合理,更强大
1. 三种状态:pending(进行中)/resolved(完成)/rejected(失败)
2. promise的api
- Promise.resolve()的作用将现有对象转为Promise对象resolvedl
- Promise.reject()也是返回一个Promise对象,状态为rejected
- then()成功的回调
- catch()发生错误的回调函数
- Promise.all()适合用于所有的结果都完成了才去执行then()成功的操作
- Promise.race()的作用也是同时执行多个实例,只要有一个实例改变状态,Promise就改为那个实例所改变的状态
#### cookie
- Cookie又叫会话跟踪技术是由Web服务器保存在用户浏览器上的小文本文件,它可以包含相关用户的信息
- cookie的特点
  - 禁用Cookie后,无法正常注册登陆
  - cookie是与浏览器相关的,不同浏览器之间所保存的cookie也是不能互相访问的
  - Cookie可以被删除。因为每个cookie都是硬盘上的一个文件
  - cookie安全性不够高-xss攻击
- localStorage sessionStorage cookie的区别
  - 首先总的来说,三者都是用于持久化数据存储的手段,都是存储在浏览器端,且同源(协议,端口号,都域名相同)
  - localStorage和sessionStorage都是Web存储,大小5M左右,完全存储在客户端,它们是因为本地存储数据而存在
  - cookies也是存储在浏览器端的,大小不超过4k,由Web服务器保存在用户浏览器上的小文本文件
  - localStorage属于永久性存储,而sessionStorage属于当会话结束(关闭浏览器)的时候,存储的值会被清空,而cookie是通过设置过期时间来存储的

- 添加cookie
// document.cookie=‘key = value ; expires=过期时间’;
// document.cookie='name=zhangsan';
// document.cookie='age=100';
- 获取cookie
addcookie('name','zhangsan',10);
addcookie('age','100',10);
addcookie('sex','男',10);
//获取cookie
// document.cookie
//alert(document.cookie);//name=zhangsan; age=100; sex=男
- 删除cookie
// 将cookie的过期时间设为一个过去的时间。
function delcookie(key){
    addcookie(key,'',-1);
}

delcookie('age');
delcookie('sex');
#### 闭包

- 浏览器垃圾回收机制的原理:变量使用完成,变量被销毁,函数一旦执行完成,函数内部的变量就不存在了,被销毁了
- 闭包的概念:函数嵌套函数(定义在一个函数内部的函数)。对于函数内部的变量形成闭合的作用域
// (function(){//闭包的写法:对于函数内部的变量形成闭合的作用域。
//     var a=1;
// })();
- 闭包的形成:与变量的作用域以及变量的生存周期密切相关,变量的作用域,就是指变量的有效范围
- js对变量生命周期的规则
  - 生存周期对于全局变量是永久的,除非我们主动销毁这个全局变量。(垃圾回收机制)
  - 而对于在函数内用 var 关键字声明的局部变量来说,当退出函数时,它们都会随着函数调用的结束而被销毁
- 闭包就是能够读取其他函数内部变量的函数。(函数嵌套函数,定义在一个函数内部的函数)
- 闭包的特点
  - 在一个函数内部定义另外一个函数,并且返回内部函数或者立即执行内部函数
  - 内部函数可以读取外部函数定义的局部变量
  - 让局部变量始终保存在内存中。也就是说,闭包可以使得它诞生环境一直存在
- 闭包的弊端:函数内部的变量始终保存在内存中,造成浏览器的垃圾回收机制失败。常驻在内存中,影响性能。手动销毁进而会引起IE浏览器的内存泄漏
- 内存泄漏:每一个变量都会绑定一个使用次数的计数器,当这个变量的使用次数为0,垃圾回收机制将其回收,如果说垃圾回收机制又无法回收,称之为内存泄漏。

#### 原型链
- 原型链:实例对象和原型之间的连接
- prototype属性:每一个函数都有一个prototype原型属性
- __proto__属性:每一个对象都有一个__proto__原型属性,指向构造函数的原型
- instanceof:判断一个对象是否是一个构造函数(类)的实例,返回布尔值
- constructor:构造函数,js的属性,获取实例对象的构造函数
- hasOwnProperty():看是不是对象自身下面的属性, 只在属性存在于实例中时才返回 true。 (不是通过原型链继承的)
- in操作符,和hasOwnProperty一样的意义,包括继承的
- typeof instanceof constructor toString 都能进行类型检查,最好的是toString

Object.prototype.toString.call(3) // "[object Number]"
Object.prototype.toString.call('') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(Math) // "[object Math]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call([]) // "[object Array]"

```

模式

  1. 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点
  • 实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象
  1. 惰性单例:指的是在需要的时候才创建对象实例。惰性单例是单例模式的重点,这种技术在实际开发中非常有用
  2. 组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构
  • 组合模式就是用小的子对象来构建更大的对象,而这些小的子对象本身也许是由更小的“孙对象”构成的
  • 组合模式使得用户对单个对象和组合对象的使用或者操作具有一致性
  1. 发布/订阅模式
  • 又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
  1. 工厂模式
  • 是为了解决多个类似对象声明的问题;也就是为了解决实列化对象产生重复的问题
  • 优点:能解决多个相似的问题
  • 缺点:不能知道对象识别的问题(对象的类型不知道)
  • 弊端:无法解决识别问题。对象来自于Object。(代码中可见的)
  1. 代理模式:是为一个对象提供一个代用品或占位符,以便控制对它的访问
  2. 适配器模式:作用是解决两个软件实体间的接口不兼容的问题。使用适配器模式之后,原本由于接口不兼容而不能工作的两个软件实体可以一起工作
  • 适配器模式是一种“亡羊补牢”的模式,没有人会在程序的设计之初就使用它。因为没有人可以完全预料到未来的事情
01-02 19:45