前后端数据交互

Frank
  • 基础知识
  • HTTP
  • Ajax
  • axios
大约 14 分钟约 4257 字...

// TODO:重整

前后端数据交互

初始前后端通信

前后端通信方式什么?

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

前端向后端发送数据:

1.登录功能

2.搜索功能

后端向前端发送数据:

页面上的图、文字等内容

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

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

  2. 概念解释

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

前后端的通信方式

  1. 使用浏览器访问网页

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

  1. Html 的标签

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

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

  1. Ajax Fetch

服务端职责

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

服务端处理数据:路由

路由和 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请求响应的过程

  • 浏览器地址栏输入 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 中的数组

注意事项

  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
上次编辑于:
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.14.1