Ajax和Git-自我总结

Ajax 知识点

1. 客户端与服务器通信的过程

  • 客户端与服务器之间的通信过程,分为请求 - 响应两个步骤。
    • 请求的概念:客户端通过网络去找服务器要资源的过程,叫做“请求”
    • 响应的概念:服务器把资源通过网络发送给客户端的过程,叫做“响应”

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m8q6gyLP-1650621958357)(./images/TongXinGuoCheng.png)]

2. URL地址

  • URL 地址用来表示服务器上每个资源的确切访问路径

  • 一个标准的 URL 地址主要由以下 4 个部分构成

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FrElN0Y9-1650621958359)(./images/URL.png)]

    • URL 地址 - 协议(protocol)
      • 概念:协议是网络协议的简称,用来保证通信的双方能读懂彼此发送过来的消息内容。
    • URL 地址 - 主机名(hostname)
      • 概念:主机名用来标识互联网中服务器的唯一性。
      • 好处:通过主机名,可以保证客户 端在万千的服务器中,找到自己想 访问的那台服务器!
    • URL 地址 - 端口号(port)
      • 概念:端口号是 0 - 65535 之间的整数,它的主要作用是表示一台计算机中的特定进程所提供的服务。
      • 注意:默认是:80端口,可以省略,80端口是网站的默认端口,省略就是80端口
    • URL 地址 - 路径(path)
      • 概念:路径用来表示资源在服务器上具体的存放位置。

3. 什么是 Ajax

  • 客户端网页向服务器请求数据的技术

4. Ajax请求数据的5种方式

  • 客户端浏览器在请求服务器上的数据时,根据操作性质的不同,可以分为以下 5 种常见的操作
    1. POST – 向服务器新增数据
    2. GET – 从服务器获取数据
    3. DELETE – 删除服务器上的数据
    4. PUT – 更新服务器上的数据(侧重于完整更新:例如更新用户的完整信息)
    5. PATCH – 更新服务器上的数据(侧重于部分更新:例如只更新用户的手机号)

5. axios

  • axios(发音:艾克C奥斯) 是前端圈最火的、专注于数据请求的库。
  • 中文官网地址:http://www.axios-js.com/
  • 英文官网地址:https://www.npmjs.com/package/axios

6. GET请求 和 POST请求 有什么区别

  • GET 请求只能在 URL 中携带少量的数 据
  • POST 请求适合用来提交大量的数 据
  • 结论:POST 为了能够提交大量的数据,所以没有把数据拼接到 URL 的末尾;而是放到了独立的“请求体”中。

7. 什么是请求报文和响应报文

  • 客户端与服务器通信的过程是基于请求响应的。其中:
    • 请求报文规定了客户端以什么格式把数据发送给服务器
    • 响应报文规定了服务器以什么格式把数据响应给客户端

8. http 响应状态码

  • 概念:http 响应状态码(Status Code)由三位数字组成,用来标识响应成功与否的状态。
  • 作用:客户端浏览器根据响应状态码,即可判断出这次 http 请求是成功还是失败了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cwlCLoIx-1650621958365)(./images/http响应状态码.png)]

  • 常见 http 状态码

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pVKCvx9H-1650621958367)(./images/常见http状态码.png)]

9. 接口的概念

  • 使用 Ajax 请求数据时,被请求的 URL 地址,就叫做数据接口(简称:接口或 API 接口)。
  • 例如
    • http://www.liulongbin.top:3009/api/getbooks 获取图书列表的接口(GET 请求)
    • http://www.liulongbin.top:3009/api/addbook 添加图书的接口(POST 请求)

9.1 接口文档

  • 接口文档就是接口的使用说明书,它是我们调用接口的依据。

  • 请参考一个现成的接口文档

    • https://www.showdoc.com.cn/ajaxapi?page_id=3753563065735122

9.2 接口测试工具

  • 测试工具:Postman
  • 下载地址::https://www.postman.com/downloads/

10. 表单的三部分

  • 网页中采集数据的表单由三个部分组成,分别是:表单标签表单域表单按钮
  1. HTML 的 <form> 就是表单标签,它是一个“容器”,用来将页面上指定的区域划定为表单区域
  2. 表单域提供了采集用户信息的渠道,常见的表单域有:input、textarea、select 等。
    • 注意:每个表单域必须包含 name 属性,否则用户填写的信息无法被采集到
  3. 当表单数据填写完毕后,用户点击表单按钮,会触发表单的提交操作,从而把采集到的数据提交给服务器
    • 注意:
      • type=“submit” 表示提交按钮的意思
      • type 属性的默认值就是 submit,因此 type=“submit” 可以省略不写

11. 同源策略&跨域

  1. 什么是同源:

    指的是两个url地址具有相同的协议、主机名、端口号

  2. 什么是跨域:

    同源指的是两个 URL 的协议、主机名、端口号完全一致,反之,则是跨域。

  3. 什么是同源策略:

    是浏览器提供的一个安全功能

    浏览器的同源策略规定:不允许非同源的 URL 之间进行资源的交互。

Ajax 各种语法

1. axios 的基本使用

url: 地址

method: 请求方式,不写默认是 GET

  • axios(发音:艾克C奥斯) 是前端圈最火的、专注于数据请求的库。
  • 中文官网地址:http://www.axios-js.com/
  • 英文官网地址:https://www.npmjs.com/package/axios
<!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>axios的基本使用</title>
  <!-- 1. 引入 axios.js 文件 -->
  <script src="./lib/axios.js"></script>
</head>
<body>
  <script>
    // 2. 调用 axios
    // 调用后就会发起请求
    axios({
      // 1. URL 地址
      url: ' http://www.liulongbin.top:3009/api/getbooks',
      // 2. method 请求方式,不写默认是 GET
      method: 'GET'
    }).then((res) => {
      // 在 then 回调中获取数据,回调函数的参数就是我们要获取的数据
      console.log(res);
    })
  </script>
</body>
</html>

2. 参数 - params

语法:params: {id: 1}

<!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>
  <script src="./lib/axios.js"></script>
</head>
<body>
  <script>
    axios({
      method: 'GET',
      // 查询参数的本质形式 
      url: ' http://www.liulongbin.top:3009/api/getbooks',
      // url 后面拼接 ? 参数名=参数值&参数名=参数值
      // url: ' http://www.liulongbin.top:3009/api/getbooks?id=1',
      // params 指定查询参数
      params: {
        // 参数
        id: 1
      }
    }).then((res) => {
      // res 从服务器获取到的数据
      console.log(res);
    })
  </script>
</body>
</html>

3. url编码

encodeURI() 编码

decodeURI() 解码

<script>
  // 在绝大部分情况下是不需要手动的进行编码的转换,因为浏览器会自动的将中文等特殊字符进行转换
  // 记住浏览器会自动进行url编码转码

  // encodeURI() 编码
  // 将中文转换成utf8编码
  console.log( encodeURI('西游记') ) // %E8%A5%BF%E6%B8%B8%E8%AE%B0
  // decodeURI() 解码
  // 将编码转换成中文
  console.log(decodeURI('%E8%A5%BF%E6%B8%B8%E8%AE%B0'))// 西游记
</script>

4. 套壳后的结果

<!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>套壳后的结果</title>
  <script src="./lib/axios.js"></script>
</head>
<body>
  <script>
    axios({
      url: 'http://www.liulongbin.top:3009/api/getbooks',
      method: 'GET',
      params: {
        bookname: '西游记'
      }
    }).then(({ data:res }) => {
      // res 是 axios 把服务器返回的数据进行套壳后的结果
      // 服务器的数据在 res 的 data 中
      // 解构赋值可以解决使用数据啰嗦问题
      // 1. 参数必须有括号 () => {}
      // 2. 在括号种声明花括号 ({}) => {}
      // 3. 在花括号中声明你要取出来使用的属性名 ({ data })
      // 4. 如果需要把属性更改成别名在属性名后面添加 :别名 ({ data:res })
      console.log(res.data)
    })
  </script>
</body>
</html>

5. 使用axios发起POST请求

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>使用axios发起POST请求</title>
  <script src="./lib/axios.js"></script>
</head>
<body>
<script>
  // 发起一个 POST 请求,添加数据
  axios({
    url: 'http://www.liulongbin.top:3009/api/addbook',
    method: 'POST',
    // 提交要添加的(参数)
    // POST 请求的参数要放在 data 对象中
    data: {
      // 以下参数都是后端告诉我们的
      // 图书名
      bookname: '哈喽哈喽',
      // 作者名
      author: 'XXX',
      // 出版社
      publisher: 'XXX'
    }
  }).then(({ data }) => {
    console.log(data)
  })
</script>
</body>
</html>

6. form表单

表单域:用来收集信息,一定要有 name 属性, name 的值就是 参数名

表单按钮:用于提交数据的按钮

type 默认是 submit,可以省略不写,不能写别的

<!-- 表单标签 -->
<form action="">
  <!-- 表单域:用来收集信息,一定要有 name 属性, name 的值就是 参数名 -->
  <input type="text" name="username">
  <input type="password" name="password">

  <!-- 表单按钮:用于提交数据的按钮 -->
  <!-- type 默认是 submit,可以省略不写,不能写别的 -->
  <!-- <input type="submit" value="提交"> -->
  <button type="submit">提交</button>
</form>

6.1 表单 GET 方式提交

action: 接口的 url 地址 把表单采集到的数据,提交到哪个接口中

method: GETPOST 数据的提交方式(默认值为 GET

enctype: application/x-www-form-urlencoded – 数据的编码格式。具体指的是:

multipart/form-data 把表单数据提交给服务器之前,如何对将要提交的数据进行编码

text/plain(很少用) (默认值 application/x-www-form-urlencoded

注意:enctype 属性只能搭配 POST 提交方式一起使用;如果是 GET 提交,则 enctype 没有意义!

<!-- 使用 form 表单做 GET 方式的提交 -->
<!-- 指定接口地址和请求 -->
<form action="http://www.liulongbin.top:3009/api/form" method="GET">
  <div>
    <span>用户名:</span>
    <input type="text" name="username">
  </div>
  <div>
    <span>密码:</span>
    <input type="password" name="password">
  </div>
  <button type="submit">提交</button>
</form>

6.2 表单 POST 方式提交

<!-- 使用 form 表单做 POST 方式的提交 -->
<!-- 指定接口地址和请求 -->
<!-- enctype 默认 为application/x-www-form-urlencoded,所以一般可以省略不写 -->
<form action="http://www.liulongbin.top:3009/api/form" method="POST" enctype="application/x-www-form-urlencoded">
  <div>
    <span>用户名:</span>
    <input type="text" name="username">
  </div>
  <div>
    <span>密码:</span>
    <input type="password" name="password">
  </div>
  <button type="submit">提交</button>
</form>

6.3 enctype属性的区别

  • enctype属性的作用:把请求体里面的参数进行编码,GET 没有请求体,在发送 GET 请求时设置该属性没有意义

  • 功能:约定参数格式

  1. application/x-www-form-urlencoded 最常用,参数都是文字、数字、布尔,不写默认就是该值

  2. multupart/form-data 上传文件

  3. text/plain 几乎不用,纯文本

6.4 结合from和ajax

from只用来收集数据

ajax负责提交

submit 提交事件 阻止默认行为 e.preventDefault()

7. axios请求方法的别名

  1. GET的请求方法的别名

    语法:axios.get()

    第一个参数,必填,url地址

    第二个参数,选填,对象,对象中设置params,参数

  2. POST 请求方法的别名

    第一个参数,必填,url地址

    第二个参数,选填,直接就是参数对象

<!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>axios请求方法的别名</title>
</head>
<body>
  <script src="./lib/axios.js"></script>
  <script>
    // 1. GET的请求方法的别名
    // 语法:axios.get()
    // 第一个参数,必填,url地址
    // 第二个参数,选填,对象,对象中设置params,参数
    // 1.1 没有传参
    axios.get('http://www.liulongbin.top:3009/api/get').then(({data}) => {
      console.log(data);
    })
    // 1.2 传参
    axios.get('http://www.liulongbin.top:3009/api/get',{
      params: {
        name: 'hh',
        age: 99
      }
    }).then(({data}) => {
      console.log(data);
    })

    // 2. POST 请求方式
    // 第一个参数,必填,url地址
    // 第二个参数,选填,直接就是参数对象
    // 2.1 没有参数
    axios.post('http://www.liulongbin.top:3009/api/post').then(({data}) => {
      console.log(data);
    })
    // 2.1 传参
    axios.post('http://www.liulongbin.top:3009/api/post',{
      name: 'HiHi',
      age: 24
    }).then(({data}) => {
      console.log(data);
    })
  </script>
</body>
</html>

8. 设置请求的全局根路径

axios.defaults.baseURL = '根路径'

<script src="./lib/axios.js"></script>
<script>
  // 设置全局请求根路径
  axios.defaults.baseURL = 'http://www.liulongbin.top:3006'
// 设置好全局根路径后,后续的请求就不用在添加根路径
axios.get('/api/get').then(res => {
  console.log(res);
})
</script>

9. 拦截器

  • 什么是拦截器

    拦截器(interceptors)用来全局拦截 axios 的每一次请求与响应。

  • 好处:可以把每个请求中,某些重复性的业务代码封装到拦截器中,提高代码的复用性。

<script src="./lib/axios.js"></script>
<script>
  // 什么是拦截器
  // 拦截器(interceptors)用来全局拦截 axios 的每一次请求与响应。
  // 好处:可以把每个请求中,某些重复性的业务代码封装到拦截器中,提高代码的复用性。
  // 1. axios拦截器可以拦截什么?
  // 拦截axios每一次的请求和响应
  // 2. 拦截器的好处是什么?
  // 可以封装请求和响应中重复的业务代码

  // 添加请求拦截器
  axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    // 打开弹窗
    loading.style.display = 'block'
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

  // 添加响应拦截器
  axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    // 关闭弹窗
    loading.style.display = 'none'
    return response;
  }, function (error) {
    // 对响应错误做点什么
    // 失败也需要关闭弹窗
    loading.style.display = 'none'
    return Promise.reject(error);
  });


  const get = document.querySelector('#get')
  const post = document.querySelector('#post')
  const loading = document.querySelector('#loading-box')

  get.addEventListener('click', function() {
    // 请求打开弹窗
    // loading.style.display = 'block'
    axios.get('http://www.liulongbin.top:3009/api/get').then(({data}) => {
      // 请求关闭弹窗
      // loading.style.display = 'none'
      console.log(data);
    })
  })
  post.addEventListener('click', function() {
    // 请求打开弹窗
    // loading.style.display = 'block'
    axios.post('http://www.liulongbin.top:3009/api/post').then(({data}) => {
      // 请求关闭弹窗
      // loading.style.display = 'none'
      console.log(data);
    })
  })
</script>

10. 使用FormData

FormData

概念:FormData 是浏览器提供的一个 WebAPI,它以键值对的方式存储数据。

作用:FormData 配合 Ajax 技术,能够向服务器发送 multipart/form-data 格式的请求体数据。

典型应用场景:FormData + Ajax 技术实现文件上传的功能。

<script src="./lib/axios.js"></script>
<script>
  // FormData
  // 概念:FormData 是浏览器提供的一个 WebAPI,它以键值对的方式存储数据。
  // 作用:FormData 配合 Ajax 技术,能够向服务器发送 multipart/form-data 格式的请求体数据。
  // 典型应用场景:FormData + Ajax 技术实现文件上传的功能。

  const fd = new FormData()
fd.append('username', '张三')
fd.append('age', 20)
// 无法直接用log查看
// console.log(fd)
// 1. fd.get 方法接收数据名作为参数,作用是获取与数据名对应值
console.log(fd.get('username'))

// 2.fd.delete 方式接收数据名作为参数,作用删除数据名对应的数据
fd.delete('username')
console.log(fd.get('username'))
// 3.forEach()
fd.forEach((value, key) => {
  console.log(key + ':' + value);
})
</script>

11. FormData结合ajax发送数据

<script src="./lib/axios.js"></script>
<script>
  // 准备 FormData 数据
  const fd = new FormData()
fd.append('name', 'Hii')
fd.append('age', '24')
// 使用 ajax 发送请求
axios.post('http://www.liulongbin.top:3009/api/formdata', fd).then(({data}) => {
  console.log(data);
})
</script>

12. XMLHttpRequest

  • 是浏览器内置的一个构造函数
  • 作用:基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。

12.1 xhr的基本使用

  1. 创建 XMLHttpRequest 对象 – readyState 为 0

    const xhr = new XMLHttpRequest()

  2. 调用 open 方法,设置请求方式和请求地址 – readyState 为 1

    第一个参数:请求方式

    第二个参数:请求的地址

    xhr.open('请求方式', '请求地址')

  3. 调用 send 方法,发起请求 – readyState 为 2

    xhr.send()

      • readyState 为 3,表示数据正在传输的过程中
  4. 监听事件(两种形式),获取服务端返回的数据

    load 事件是后台返回数据全部加载完毕的事件

    readyState 为 4,表示传输完毕

// 1. 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest()
// readyState 为 0

// 2. 调用 open 方法,设置请求方式和请求地址
// 第一个参数:请求方式
// 第二个参数:请求的地址
xhr.open('get', 'http://www.liulongbin.top:3009/api/get')
// readyState 为 1

// 3. 调用 send 方法,发起请求
xhr.send()
// readyState 为 2

// readyState 为 3,表示数据正在传输的过程中

// 4. 监听事件(两种形式),获取服务端返回的数据
// 第一种形式
  // load 事件是后台返回数据全部加载完毕的事件
  xhr.addEventListener('load', function() {
    // 获取服务器的返回结果
    console.log(xhr.response)
  })
// 第二种形式
	xhr.addEventListener('readystatechange', function() {
    // readyState 为 4,表示传输完毕
    if ( xhr.readyState === 4 ) {
      // 传输完成,可以获取数据了
      console.log(xhr.response)
    }
  })

12.2 使用xhr发起get请求

在后面直接拼接要传的参数

<script>
  const xhr = new XMLHttpRequest()
xhr.open('GET', 'http://www.liulongbin.top:3009/api/get?name=张三&age=18')
xhr.send()
xhr.addEventListener('load', function() {
  console.log(xhr.response);
})
</script>

12.3 使用xhr发起post请求

  1. 请求体参数应放在send参数里

  2. 设置请参数的编码格式

    2.1 设置请求头 xhr.setRequestHeader('设置请求头', '编码格式')

    • 第一个参数为设置请求头(固定单词)
    • 第二个参数为设置编码格式
<script>
const xhr = new XMLHttpRequest()
// 发起 post 请求,open的第一个参数要设置成post
// 在 url 后面的参数叫做查询参数
xhr.open('POST', 'http://www.liulongbin.top:3009/api/post')
// 请求体参数应放在send参数里
// 设置请参数的编码格式
// 设置请求头
// 第一个参数为设置请求头(固定单词)
// 第二个参数为设置编码格式
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// send 字符串
xhr.send('name=张三&age=18')
xhr.addEventListener('load', function() {
  console.log(xhr.response);
})
</script>

13. 数据交换格式

数据交换格式:

​ 数据交换格式,就是服务器端与客户端之间数据传输的格式。

两种数据交换格式:

​ 1. XML(很少用)

​ 2. JSON(主流)

14. JSON字符串

JSON 格式

​ 用字符串表示对象或数组 就是 JSON

格式规定:

  1. key 必须使用双引号包裹
  2. value 必须是 字符串(必须用双引号包裹)、数字、布尔值、null、数组、对象类型

JSON 操作:

  1. 序列化:把真实的数据转换为字符串的过程
  2. 反序列化:把字符串转换为真实数据的过程
// 数据交换格式
// 数据交换格式,就是服务器端与客户端之间数据传输的格式。
// 两种数据交换格式:
// 1. XML(很少用)
// 2. JSON(主流)

// JSON 格式
// 用字符串表示对象或数组 就是 JSON

// 格式规定:
// 1. key 必须使用双引号包裹
// 2. value 必须是 字符串(必须用双引号包裹)、数字、布尔值、null、数组、对象类型

// JSON 格式写法
const data = '{"name":"张三","age":18,"isOver":false}'
// 数组中只能放 字符串(必须用双引号包裹)、数字、布尔值、null、数组、对象(符合json对象字符串的规则)
const arr = '["abc",18,{"name":"zs"}]'

// JSON 操作
// 1. 序列化:把真实的数据转换为字符串的过程
// 2. 反序列化:把字符串转换为真实数据的过程

// 序列化:把真实数据转换为字符串的过程
// 将对象或数组转换成 JSON 字符串
console.log( JSON.stringify({name: "张三", age: 20}) )

// 反序列化:把字符串转换为真实数据的过程
// 将 JSON 转换成可以操作的对象或数组
console.log( JSON.parse(data) )

15. 在 ajax 中使用 JSON

  1. 发送数据时可以发送 json

    一定要设置 json 格式的请求头

    xhr.setRequestHeader('Content-Type', 'application/json')

  2. 后端给我们返回的是 JSON 不好操作

    使用反序列化,将 json 转换成可以操作的对象

    console.log( JSON.parse(xhr.response) )

const obj = {
  name: "张三",
  age: 18
}
const xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3009/api/post')

// 发送数据时可以发送 json
// 1. 一定要设置 json 格式的请求头
xhr.setRequestHeader('Content-Type', 'application/json')
// 为了操作方便,先创建对象,使用序列化将对象转换成json
xhr.send( JSON.stringify(obj) )

xhr.addEventListener('load', function() {
  // 后端给我们返回的是 JSON 不好操作
  // 使用反序列化,将 json 转换成可以操作的对象
  console.log( JSON.parse(xhr.response) )
})

16. 案例 - 封装自己的 ajax

js 文件

html 文件

  • js 文件
function ajax(options) {
  // 处理 params 参数
  // 先判断调用者是否传递了 params 参数对象
  if (options.params) {
    // 准备数组
    const arr = []
    // 遍历 params 对象
    for(let key in options.params) {
      // 按照 key = value 的格式保存到数组中
      arr.push(`${key}=${options.params[key]}`)
    }
    // 判断数组中是否有内容,判断 params 是不是空
    if(arr.length > 0) {
      options.url += '?' + arr.join('&') 
    }
  }

  // 1. 创建 xhr
  const xhr = new XMLHttpRequest()
  // 2. 调用 open 设置请求方式和请求地址,通过传递过来的参数设置
  xhr.open(options.method, options.url)

  // 处理 data 的参数
  // POST 的时候才需要处理 data
  if ( options.method.toUpperCase() === 'POST' && options.data ) {
    // 1. 如果 options.data 是一个对象,application/json
    if ( typeof options.data === 'object' && !(options.data instanceof FormData) ) {
      // 设置编码格式
      xhr.setRequestHeader('Content-Type', 'application/json')
      // 发送数据
      xhr.send( JSON.stringify(options.data) )
    }
    // 2. 如果 options.data 是一个字符串,application/x-www-form-urlencoded
    if ( typeof options.data === 'string' ) {
      // 设置编码格式
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      // 发送数据
      xhr.send(options.data)
    }
    // 3. 如果 options.data 是一个FormData
    if ( options.data instanceof FormData ) {
      // 直接发给后台
      xhr.send(options.data)
    }
  } else {
    // 3. 调用 send
    xhr.send()
  }

  // 4. 监听完成事件
  xhr.addEventListener('load', function() {
    // 把服务器返回的数据传给函数的调用者,调用 success 回调
    options.success( JSON.parse(xhr.response) )
  })
}
  • 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>封装自己的ajax</title>
</head>
<body>
  
  <script src="./js/myAjax.js"></script>
  <script>
    let fd = new FormData()
    fd.append('name', 'zs')
    fd.append('age', 18)
    ajax({
      method: 'POST',
      url: 'http://www.liulongbin.top:3009/api/post',
      // data: fd,
      // data: {name:'zs', age:18},
      data: 'name=zs&age=18',
      success: function (res) {
        console.log(res);
      }
    })
  </script>
</body>
</html>

17. 防抖(debounce)

用来优化 ajax 的

频繁触发某个操作时,只执行最后一次

过程:

  1. 在事件外面声明定时器 id 变量
  2. 在每一次事件触发时都干掉上一次的 timer
  3. 定义一个延迟定时器,在定时器内执行事件的逻辑,保存定时器 id
<script>
  // 需求:输入时打印输入框的文字
  // 1. 在事件外面声明定时器 id 变量
  let timer = null
  let inp = document.querySelector('.ipt')
  inp.addEventListener('input', function() {
    // 用 console.log 来替代 ajax 请求
    // 防抖:只打印输入完成的全部内容,之前输入的不做处理 - 防抖
    // 2. 在每一次事件触发时都干掉上一次的 timer
    clearTimeout(timer)
    // 3. 定义一个延迟定时器,在定时器内执行事件的逻辑,保存定时器 id
    timer = setTimeout(() => {
      console.log(inp.value)
    }, 500)
  })
</script>

18. 节流(throttle)

  1. 节流阀,标识符,标记当前是否有一个定时器
  2. 在事件中判断是否有一个定时器
  3. 在定时任务纲要创建时,把节流阀修改状态
  4. 创建定时器 – 要执行的逻辑
  5. 把节流阀修改回初始状态
<script>
  // 需求每点赞一次就像后台发送一次请求
	const box = document.querySelector('#box')
  // 1. 节流阀,标识符,标记当前是否有一个定时器
  let isOk = false
	box.addEventListener('click',function() {
  // 2. 在事件中判断是否有一个定时器
  // 如果有就 return,后续代码不再执行,如果没有就继续执行
  if (isOk) return
  // 3. 在定时任务纲要创建时,把节流阀修改状态
  isOk = true
  // 4. 创建定时器
  setTimeout(() => {
    // 要执行的逻辑
    console.log('你点击了1次');
    // 5. 把节流阀修改回初始状态
    isOk = false
  },3000)
})
</script>

Git 总结

1. 什么是 Git

  • Git 是一个开源的分布式版本控制系统,是目前世界上最先进、最流行的版本控制系统。

2. Git 中的三个区域

  • 分别是工作区、暂存区、Git仓库
    1. 工作区:正在写的项目文件夹区域
    2. 暂存区:临时存放已经完成的文件区域
    3. Git仓库:把最终存放的文件区域

3. Git 中的三个状态

  • 本别是已修改、已暂存、已提交
    1. 已修改:表示修改了文件,但还没 将修改的结果放到暂存区
    2. 已暂存:表示对已修改文件的当前 版本做了标记,使之包含 在下次提交的列表中
    3. 已提交:表示文件已经安全地保存 在本地的 Git 仓库中

4. 本的 Git 工作流程

  1. 在工作区中修改文件
  2. 将你想要下次提交的更改进行暂存
  3. 提交更新,找到暂存区的文件,将快照永久性 存储到 Git 仓库

5. 安装并配置 Git

5.1 在 Windows 中下载并安装 Git

在开始使用 Git 管理项目的版本之前,需要将它安装到计算机上。可以使用浏览器访问如下的网址,根据自 己的操作系统,选择下载对应的 Git 安装包: https://git-scm.com/downloads

5.2 配置用户信息

-安装完 Git 之后,要做的第一件事就是设置自己的用户名和邮件地址。因为通过 Git 对项目进行版本管理的 时候,Git 需要使用这些基本信息,来记录是谁对项目进行了操作:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8J2MNmTC-1650621958370)(./images/git配置.png)]

5.3 Git 的全局配置文件

通过 git config --global user.name 和 git config --global user.email 配置的用户名和邮箱地址,会被写 入到 C:/Users/用户名文件夹/.gitconfig 文件中。这个文件是 Git 的全局配置文件,配置一次即可永久生效 。 可以使用记事本打开此文件,从而查看自己曾经对 Git 做了哪些全局性的配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sQ37yDkc-1650621958371)(./images/git5.3.png)]

5.4 检查配置信息

除了使用记事本查看全局的配置信息之外,还可以运行如下的终端命令,快速的查看 Git 的全局配置信息:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WDKpSFGV-1650621958372)(./images/git5.4.png)]

6. Git 基本操作

6.1 获取Git仓库 - git init

注:每个项目用一次

git init 将本地的目录初始化为Git仓库

  1. 将本地的目录初始化为Git仓库(本地已有或刚创建项目时)
    1. 打开项目文件夹
    2. 在该文件夹中右键->Git Bash Here 打开Git命令
    3. 在命令行输入 git init
  2. 从远程服务器克隆Git仓库(项目要保存到网上或者公司的服务器已有项目)

6.2 查看文件状态 - git status

git status **【推荐】**查看文件状态

git status -s 以精简方式查看文件状态,这个是下面的简写

git status --short 以精简方式查看文件状态

git status
# 以精简方式查看文件状态,下面两个命令是一回事,第一个是第二个的简写
git status -s
git status --short
# 未跟踪文件前面有红色的 ?? 标记,

6.3 将工作区的代码提交到暂存区 - git add .

注:每一个新文件或每对一个文件进行修改后

git add 文件名 将工作区某一个文件的代码提交到暂存区

git add . **【推荐】**将工作区的所有文件的代码提交到暂存区

git add 文件名
# 下面这条是常用名,将文件夹内所有的文件(新建的文件或已修改的文件)都添加到暂存区
git add .

6.4 将暂存区的文件提交到Git仓库 - git commit -m "本次提交的注释消息"

建议:每完成一个功能提交一次

git commit -m "本次提交的注释消息"

git commit -m "本次提交的注释信息"

6.5 流程

# 1. 在项目文件夹中初始化git仓库,一个项目一次
git init
# 2. 将新建文件或修改后的文件提交到暂存区
git add .
# 3. 将暂存区的文件提交到git仓库
git commit -m "提交的注释消息"

# 2-3步是频繁执行,只要有新内容提交,就需要执行

7. Git 忽略文件

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 在这种情况下,我们 可以创建一个名为 .gitignore 的配置文件,列出要忽略的文件的匹配模式。

  • 文件 .gitignore 的格式规范如下:
    1. 以 # 开头的是注释
    2. 以 / 结尾的是目录
    3. 以 / 开头防止递归
    4. 以 ! 开头表示取反
    5. 可以使用 glob 模式进行文件和文件夹的匹配(glob 指简化了的正则表达式)
      • 所谓的 glob 模式是指简化了的正则表达式:
        1. 星号 * 匹配零个或多个任意字符
        2. [abc] 匹配任何一个列在方括号中的字符 (此案例匹配一个 a 或匹配一个 b 或匹配一个 c)
        3. 问号 ? 只匹配一个任意字符
        4. 在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹 配所有 0 到 9 的数字)
        5. 两个星号 ** 表示匹配任意中间目录(比如 a/**/z 可以匹配 a/z 、 a/b/z 或 a/b/c/z 等)

8. 远程创建仓库连接

  1. 创建的仓库(创建时,最后有复选框,勾选和不勾选会导致了两种关联方式)

    1. 不勾选复选框(创建了空仓库)

      1. 在本地创建项目文件夹
      2. git init
      3. 保证文件夹内有文件(建议新建一个README.md文件,这个是网页首页显示的)
      4. git add .
      5. git commit -m "备注"
      6. git remota add origin 仓库地址
      7. git push -u origin "master"(-u origin master设置默认推送)
    2. 勾选复选框(创建非空仓库,或者到单位给一个非空的项目)

      1. 进入到要存放的项目文件夹
      2. 在文件夹上打开命令行
      3. git clone 仓库地址(克隆/下载复制来的地址)
      4. 不需要做任何配置,直接进行后续的开发
    3. 开发

      1. 每完成一个功能(页面)

      2. git add .

      3. git commit -m "备注"

      4. git push

        234三个步骤重复执行

9. Git 分支

  • 分支概念:
    • 分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努 力学习SVN。
    • 如果两个平行宇宙互不干扰,那对现在的你也没啥影响。
    • 不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了Git又学会了SVN!
  • 分支在实际开发中的作用
    • 在进行多人协作开发的时候,为了防止互相干扰,提高协同开发的体验,建议每个开发者都基于分支进行项 目功能的开发
  • master 主分支
    • 在初始化本地 Git 仓库的时候,Git 默认已经帮我们创建了一个名字叫做 master 的分支。通常我们把这个 master 分支叫做主分支。
    • 作用:
      • 用来保存和记录整个项目已完成的功能代码。因此,不允许程序员直接在 master 分支上修改代码,因为这样做的风险太高,容易导致整个项目崩溃。
  • 功能分支
  • 功能分支指的是专门用来开发新功能的分支,它是临时从 master 主分支上分叉出来的,当新功能开发且测 试完毕后,最终需要合并到 master 主分支上。

10. Git 本地分支操作

  1. 查看分支列表

    # 使用如下的命令,可以查看当前 Git 仓库中所有的分支列表:
    # 注意:分支名字前面的 * 号表示当前所处的分支。
    git branch
    
  2. 创建新分支

    # 使用如下的命令,可以基于当前分支,创建一个新的分支,此时,新分支中的代码和当前分支完全一样:
    # 基于主分支上来创建的 复制主分支所有内容到新分支
    git branch 分支名
    
  3. 切换分支

    # 使用如下的命令,可以切换到指定的分支上进行开发:
    git checkout 分支名
    
  4. 合并分支

    # 切换到主分支
    git checkout 主分支名
    # 把选择的功能分支合并到主分支上
    git merge 功能分支名
    
  5. 分支的快速创建和切换

# 使用如下的命令,可以创建指定名称的新分支,并立即切换到新分支上:
get checkout -b 分支名称
  1. 删除本地分支
# 当把功能分支的代码合并到 master 主分支上以后,就可以使用如下的命令,删除对应的功能分支:
get branch -d 分支名称
  1. 遇到冲突时的分支合并

    • 发生冲突后手动选择留下哪一个或者都留下

11. Git 远程分支操作

  1. 如果是第一次将本地分支推送到远程仓库,需要运行如下的命令:

    例如:

    # -u:把本地分支和远程分支进行关联,远程的 origin 这个仓库,本地的时 list 仓库和远程的 li 分支进行关联 
    git push -u origin list:li
    注:后续在本地list分支推送到远程li分支的时候只需要 git push 就好了,不用加 -u 后的代码
    
    #-u:把本地分支和远程分支进行关联,远程的 origin 这个仓库,本地的时 list 仓库和远程的 list 分支进行关联 
    git push -u origin list
    
  2. 查看远程仓库中所有的分支列表

    git remote show 远程仓库名称
    
  3. 拉取远程分支的最新的代码

    # 从远程仓库,拉取当前分支最新的代码,保持本地分支代码和远程分支代码一致
    git pull
    
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值