跳至主要內容

前后端数据交互

Mr.Chen基础知识HTTPAjaxaxios大约 14 分钟约 4159 字

// TODO:重整

前后端数据交互

初始前后端通信

前后端通信方式什么?

前端和后端数据交互的过程<=>浏览器和服务器交互的过程

前端向后端发送数据:

1.登录功能

2.搜索功能

后端向前端发送数据:

页面上的图、文字等内容

前后端通信的过程与概念解释

  1. 前后端通信的过程
    前后端通信是在 请求-响应 中完成的

  2. 概念解释

  • 前端:浏览器端
  • 客户端:只要能和通信的就叫客户端
  • 后端:服务器端

前后端的通信方式

  1. 使用浏览器访问网页

在浏览器地址栏输入网址,按下回车

  1. Html 的标签

浏览器在解析 Html 标签的时候,遇到一些特殊的标签( link img script iframe ),会再次向服务器发送请求

还有一些标签(a,from(表单)),浏览器解析的时候,不会向服务器发送请求,但是用户可以使用他们向服务器发送请求

  1. Ajax Fetch

服务端职责

  • 处理 HTTP 请求(req,res)
  • 定义路由,供前端 Ajax 访问
  • 使用数据库,存储和查询数据

服务端处理数据:路由

::: tip 路由和 URL 的关系

GET /api/list 路由 ---> axios.get('api/list?a=1')

路由是规则,url 是具体的形式两者不同

:::

路由是服务端的入口规则,也是与前端的“约定”

路由主要包含:

  • 定义 method,如 GET,POST
  • 定义 url 规则,如/api/list/api/create
  • 定义输入Request body和输出Response body格式

HTTP 协议

初识 HTTP

http协议规定了客户端和服务端如何通讯

  • url:后端接口的地址,即前端 Ajax 请求时的地址
  • method:请求方法,如 GET POST PUT DELETE
  • 状态码:接口返回的状态,如 200 302 404 500
  • Request:请求
  • Request Body:请求时发送给后端的数据
  • Request Content-type:发送数据的格式,如 json
  • Response:响应
  • Response Body:后端返回给前端的数据
  • Response Content-type:返回数据的格式,如 json
  1. HTTP (hypeText Transfer Protocol:超文本传输协议)

HTML:超文本标记语言,超文本:原先一个个单一的文本,通过超链接将其联系起来。由原先的单一的文本变成了可无限伸、扩展的超級文本、立体文本

HTML、JS、CSS、图片、字体、音频、视频等等文件,都是通过HTTP在服务器和浏览器之间传输

每一次前后端通信,前端需要主动向后端发岀请求,后端接收到前端的请求后,可以给出响应

HTTP是一个请求-响应协议

  1. HTTP 请求响应的过程
HTTP请求响应的过程
HTTP请求响应的过程
  • 浏览器地址栏输入 URL 并回车
  • 浏览器查找当前 URL 是否存在缓存,并比较缓存是否过期
  • DNS 解析 URL 对应的 IP
  • 根据 IP 建立 TCP 连接(三次握手)
  • 发送 http 请求
  • 服务器处理请求,浏览器接受 HTTP 响应
  • 浏览器解析并渲染页面
  • 关闭 TCP 连接(四次挥手)

http 报文

  1. HTTP 报文是什么
  • 浏览器向服务器发送请求的时候,请求本身就是信息,叫请求报文
  • 服务器向浏览器发送响应时传输的信息,叫响应报文
  1. HTTP 报文格式 // TODO:复查 2022.3.22
  • 请求
  1. 请求头:起始行(黄色高亮部分)+首部(剩余部分为首部)
起始行
起始行
  1. 请求体

GET 请求没有请求体,数据是通过请求头携带

POST 请求,有请求体,数据通过请求体携带

  • 响应
  1. 响应头:起始行+首部
  2. 响应体

HTTP 方法

  1. 常用的 HTTP 方法

浏览器发送请求时采用的方法。和响应无关

GET POST PUT DELETE

用来定义对于资源采取什么样的操作的,有各自的语义

  1. HTTP 方法的语义
  • GET 获取数据 -POST 创建数据
  • PUT 更新数据(修改个人信息 修改密码) -DELETE 删除数据

这些方法虽然有各自的语义,但是并不是强制性的

3.RESTful 接口设计

一种接口设计风格, 充分利用 HTTP 方法的语义

  • 普通方法:

① 通过用户 ID 获取用户个人信息,使用 GET 方法https://www.xxx.com/api/http/getUser?id=1

② 注册新用户,使用 POST 方法https://www.xxx.com/api/http/addUser

③ 修改一个用户,使用 POST 方法https://www.xxx.com/api/http/modifuUser

③ 删除一个用户,使用 POST 方法 https://www.xxx.com/api/http/deleteUser

  • RESTful 接口风格

只需要定义一个接口:https://www.xxx.com/api/http/User

分别通过四种语义的方法:GET(获取信息)、POST(注册用户)、PUT(修改信息)、DELETE(删除信息)

GET 和 POST 方法的对比

  1. 语义:GET:获取数据,POST:创建数据

  2. 发送数据

GET 通过地址在请求头中携带数据,能携带的数据和地址的长度有关,一般最多就几 K

POST 既可以通过地址在请求头中携带数据,也可以通过请求体携带数据,能携带的数据理论上是无限量的

携带少量数据,可以使用 GET 请求。大量的数据可以使用 POST 请求

  1. 缓存:Get 可以被缓存,post 不会被缓存

  2. 安全性:GET 和 POST 都不安全

HTTP 状态码

HTTP 状态码open in new window

定义服务器对请求的处理结果,是服务器返回的

100-199=>消息:代表请求已经被接受,需要继续处理

200-299=>成功:200

300-399=>重定向:301永久重定向,除非用户手动清除缓存;302临时重定向,不会缓存;304没有修改,所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。

400-499=>请求错误:404Not Found(没有找到)

500-599=>服务器错误:500服务器内部错误,无法完成请求

ajax

Ajax 简介

Ajax即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。

Ajax中的异步:可以异步地向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,浏览器可以做自己的事. 直到成功获取响应后,浏览器才开始处理响应数据。

XML 可扩展标记语言,是前后端数据通信时传输数据的一种格式

XML 现在已经不怎么用了,现在比较常用的时JSON

Ajax其实就是浏览器与服务器之间的一种 异步通信方式

使用Ajax可以在不重新加载整个页面的情况下, 对页面的某部分进行更新

Ajax 的基本用法

Ajax想要实现浏览器与服务器之间的异步通信,需要依靠XMLHttpRequest,它是一个构造函数

  1. 创建 xhr 对象
const xhr = new XMLHttpRequest()
  1. 监听事件,处理响应

当获取到响应后,会触发 xhr 对象的readystatechange事件,可以在该事件中对响应进行处理

xhr.onreadystatechange = () => {
  if (xhr.readyState !== 4) return
  //HTTP CODE
  //获取响应后,响应的内容会自动填充xhr对象的属性
  if ((xhr.status >= 200) & (xhr.status < 300) || xhr.status === 304) {
    console.log('正常使用')
    //数据
    console.log(xhr.responseText)
  }
}

readystatechange事件监听readyState这个状态的变化 一共有 5 个状态

  • 0:未初始化,尚未调用open()
  • 1:启动,已经调用open(),但尚未调用send()
  • 2:发送,已经调用send(),当尚未接收到响应
  • 3:接收,已经接收到部分响应数据
  • 4:完成,已经接收到全部响应数据,并且可以在浏览器中使用
  1. 准备发送请求
    调用open()并不会真正发送请求,而只是做好发送请求前的准备工作
xhr
  .open
  //'http方法',
  //"地址url",true或false:是否为异步请求,一般肯定true
  ()
  1. 发送请求

调用send()正式发送请求

send()的参数是通过请求体携带的数据

xhr.send(null) //GET请求一般填null,因为GET不能通过请求体携带数据

eg:使用Ajax来完成前后端通信

const url = 'https://www.imooc.com/api/http/search/suggest?words=js'
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
  if (xhr.readyState !== 4) return
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
    console.log(xhr.responseText)
  }
}
xhr.open('get', url)
xhr.send(null)

GET 请求

  1. 携带数据
    GET请求不能通过请求体携带数据,但可以通过请求头携带, 在 url 对应的接口下添加名值对
  2. 数据编码
    如果携带的数据时非英文字母的话,比如说汉字,就需要编码之后再发送给后端,不然会造成乱码问题

POST 请求

  1. 携带数据
    POST请求主要通过请求体携带数据,同时也可以通过请求头携带
const url = 'https://www.imooc.com/api/http/search/suggest?words=js'
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
  if (xhr.readyState !== 4) return
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
    console.log(xhr.responseText)
    console.log(typeof xhr.responseText)
  }
}
xhr.open('POST', url)
//如果想发送数据,直接写在 send()的参数位置,一般是字符串
// 不能直接传递对象,需要先将对象转换成字符串的形式
xhr.send('username=alex&age=18')
  1. 数据编码:如果携带的数据时非英文字母的话,比如说汉字,就需要编码之后再发送给后端,不然会造成乱码问题

JSON

初识 JSON

  1. javascript object notation,Ajax发送和接受的一种数据格式

  2. 为什么需要 JSON

JSON 有 3 种形式,每种形式的写法都和JS中的数据类型很像,可以很轻松的和JS中的数据类型互相转换

JSON 的三种形式

  1. 简单值形式

文件名:xxx.json
JSON 的简单值形式就对应着 JS 中的基础数据类型,数字,字符串,布尔值,null

  1. 对象形式

JSON的对象形式就对应着JS中的对象

{
  "name": "张三",
  "age": 18,
  "hobby": ["足球", "乒乓球"]
}
  1. 数组形式

JSON的数组形式就对应着 JS 中的数组

::: warning 注意事项

  1. JSON 中没有underfined
  2. JSON 中的字符串必须使用双引号
  3. JSON 中是不能注释的
  4. JSON 中对象的属性名必须使用双引号,属性值如果是字符串也必须用双引号。 :::

JSON 的常用方法

  1. JSON.parse()
    可以将JSON格式的字符串解析成 JS 中的对应值
    一定要是合法的JSON字符串,否则会报错
  2. JSON.stringify() 可以将JS基本数据类型,对象或者数组转换成JSON格式的字符串
xhr.open('POST', url, true)
xhr.send(
  JSON.stringify({
    name: '张三',
    hobby: ['足球', '乒乓球'],
  })
)
  1. 使用 JSON.parse()和 JSON.stringify()封装 localStorage
const storage = window.localStorage
// 设置
const set = (key, value) => {
  storage.setItem(key, JSON.stringify(value))
}
// 获取
const get = key => {
  return JSON.parse(storage.getItem(key))
}
// 删除
const remove = key => {
  storage.removeItem(key)
}
// 清空
const clear = () => {
  storage.clear()
}

跨域

简介

向一个域发送请求,如果要请求的域和当前域是不同域,就叫跨域

不同域之间的请求,就是跨域请求

什么是不同域,什么是同域

https(协议):// www.imooc.com (域名) :443 (端口号) /course/list (路径)

  • 协议 域名 端口号 任何一个不一样 就是不同域
  • 与路径无关,路径不一样无所谓

跨域请求为什么会被阻止

  • 阻止跨域请求,其实是浏览器本身的一种安全策略---同源策略
  • 其他客户端或者服务器不存在跨域被阻止的问题

跨域解决方案

  • CORS 跨域资源共享
  • JSONP
  • 优先使用CORS ,如果浏览器不支持,使用JSONP

CORS 跨域资源共享

跨域资源共享 CORS 详解open in new window

使用 CORS 跨域的过程

① 浏览器发送请求

② 后端在响应头中添加 Access-Control-Allow-Origin 头信息

③ 浏览器接收到响应

④ 如果是同域下的请求,浏览器不会额外做什么,这次前后端通信就圆满完成了

⑤ 如果是跨域请求,浏览器会从响应头中查找是否允许跨域访问

⑥ 如果允许跨域,通信圆满完成

⑦ 如果没找到或不包含想要跨域的域名,就丢弃响应结果

CORS兼容性:IE10 及以上可以正常使用

JSONP

  1. 原理
    script 标签跨域不会被浏览器阻止
    JSONP主要就是利用SCRIPT标签,加载跨域文件
  2. 使用JSONP 实现跨域
    服务器端准备好JSONP接口
    手动加载JSONP标签或
<!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>
    <script type="text/javascript">
      const handleResponse = data => console.log(data)
    </script>
    <script src="https://www.imooc.com/api/http/jsonp?callback=handleResponse"></script>
  </body>
</html>

动态加载JSONP接口

// 动态加载JSONP接口
const script = document.createElement('script')
script.src = 'https://www.imooc.com/api/http/jsonp?callback=handleResponse'
document.body.appendChild(script)
const handleResponse = data => {
  console.log(data)
}

XHR 对象

XHR 的属性

  1. responseTyperesponse属性
  • responseText只能在没有设置responseType或者responseType=''responseType='text' 的时候才能使用
  • response可以替代responseText,默认返回字符串,可以通过responseType设置返回形式(如果设置为JSON,浏览器默认调用JSON.parse()解析成 JS 中的对应值,但服务器还是返回的是JSON格式的字符串)
xhr.responseType = 'json'
  1. timeout属性:设置请求的超时时间(单位:ms)

  2. withCredentitals 属性

  • 指定使用Ajax发送请求时是否携带Cookie
  • 使用Ajax发送请求,默认情况下,同域时,会携带Cookie,跨域时,不会
  • 最终是否能成功跨域携带Cookie,还要看服务器同不同意
xhr.withCredentials = true

XHR 方法

  1. abort():终止当前请求,一般配合 abort 事件一起使用
  2. setRequestHeader():可以设置请求头信息

HTTP content-typeopen in new window

//  请求头中的`Content-Type`字段用来告诉服务器,浏览器发送的数据是什么格式的。
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') // 对应的数据格式:'username=ased&password=asd'

xhr.setRequestHeader('Content-Type', 'application/json') // JSON格式的数据

XHR 的事件

  1. load 事件:响应数据可用时触发 推荐使用onload代替onreadystatechange
const url = 'https://www.imooc.com/api/http/search/suggest?words=js'
const xhr = new XMLHttpRequest()
xhr.addEventListener(
  'load',
  () => {
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
      console.log(xhr.response)
      console.log(typeof xhr.response)
    }
  },
  false
)
xhr.responseType = 'json'
xhr.open('GET', url, true)
xhr.send()
  1. error 事件
    请求发生错误时触发
const url = 'https://www.imooc1.com/api/http/search/suggest?words=js'
const xhr = new XMLHttpRequest()
xhr.addEventListener(
  'load',
  () => {
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
      console.log(xhr.response)
      console.log(typeof xhr.response)
    }
  },
  false
)
xhr.addEventListener('error', () => {
  console.log('访问出错拉!')
})
xhr.responseType = 'json'
xhr.open('GET', url, true)
xhr.send()
  1. abort 事件
    调用 abort()终止请求时触发
const url = 'https://www.imooc.com/api/http/search/suggest?words=js'
const xhr = new XMLHttpRequest()
xhr.addEventListener(
  'abort',
  () => {
    console.log('543629463')
  },
  false
)
xhr.addEventListener('error', () => {
  console.log('访问出错拉!')
})
xhr.responseType = 'json'
xhr.open('GET', url, true)
xhr.send()
xhr.abort()
  1. timeout 事件
var xhr = new XMLHttpRequest()
xhr.responseType = 'json'
xhr.onreadystatechange = () => {
  if (xhr.readyState !== 4) return
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
    console.log(xhr.response)
  }
}
xhr.open('GET', 'https://www.imooc.com/api/http/search/suggest?words=js')
xhr.timeout = 10
xhr.ontimeout = function (e) {
  console.log('Timeout!!')
}
xhr.send()

FormData

使用 Ajax 提交表单(避免直接提交表单跳转)

FormData 可用于发送表单数据

<body>
  <form id="login">
    <input type="text" name="username" placeholder="用户名" />
    <input type="password" name="password" placeholder="密码" />
    <input type="submit" id="submit" value="提交" />
  </form>
  <script>
    const login = document.getElementById('login')
    const btn = document.getElementById('submit')
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js'
    btn.addEventListener(
      'click',
      e => {
        // 阻止表单跳转
        e.preventDefault()
        const xhr = new XMLHttpRequest()
        xhr.addEventListener(
          'load',
          () => {
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
              console.log(xhr.response)
            }
          },
          false
        )
        xhr.open('POST', url, true)
        xhr.responseType = 'json'
        const data = new FormData(login)
        xhr.send(data)
      },
      false
    )
  </script>
</body>

FormData 的基本用法

// 通过 HTML 表单元素创建 FormData 对象
const fd = new FormData(表单元素)
xhr.send(fd)

// 通过 自身的append() 方法添加数据
const fd = new FormData(表单元素)
fd.append('age', 18)
fd.append('sex', 'male')
xhr.send(fd)

封装 Ajax

1、ajax的原理需要掌握一下。即ajax这门技术是使用XMLHttpRequest这个对象实现的,该对象有一些方法和属性,比如open()send()responseType......它们的含义是什么要知道。 2、ajax的具体实现不需要自己手动封装。 3、实际开发中会使用现成的插件,我们只需要按照插件的文档使用即可

源代码:

hand-tear-codeopen in new window

axios

  1. 基于 Promise 的 HTTP 库
  2. axios 官方文档open in new window

Fetch

Fetch API 教程open in new window

  1. 也是前后端通信的一种方式
  2. Ajax的一种替代方案,它是基于Promise
  3. Ajax的兼容性比 Fetch
上次编辑于: