前端笔记三前后端通信(http协议和Ajax)

Posted 桥本环奈粤港澳分奈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端笔记三前后端通信(http协议和Ajax)相关的知识,希望对你有一定的参考价值。

一、http协议

http协议就是前端与后端之间相互通信所遵循的协议,协议定义了传输信息的格式,信息所表示的具体的含义。

前端和后端之间沟通的信息分为两种:

  1. 前端给后端发送的信息叫做请求报文,也就是HTTP request
  2. 后端回复前端的信息叫做响应报文,也就是HTTP response

http协议最主要的内容就是定义了请求报文和响应报文的格式以及各个字段的含义。

请求报文

请求报文的结构类似下图,一共分为三个部分:请求行首部字段消息体

1. 请求行

请求行占据了请求报文第一行的位置,分为三个部分:请求方法 请求地址 协议版本,由空格隔开:

  • 请求方法 可以看做请求的类型,常见取值:GET、POST、PUT、DELETE
  • 请求地址 表示的就是这个请求要往哪里发送
  • 协议版本 协议的版本信息

2. 首部字段


一个首部字段占据一行,是以键值对的形式表示的,键与取值之间用英文冒号分隔,类似于JS当中对象属性的定义

3. 消息体


消息体和首部字段之间通过一个空行分隔开来,消息体其实就是本次请求报文当中实际包含的数据,类比于我们写信中信的内容

响应报文

响应报文分为三部分:状态行首部字段消息体

1. 状态行

状态行也是由三个字段通过空格分隔构成的,依次是:协议版本、状态码、状态码对应的文本描述。

前端根据状态码来判断本次请求是否成功,状态码的取值和含义都在http协议中有明确定义,eg:

二、Ajax

Ajax(Asynchronous javascript and XML),即异步 JavaScript 和 XML。在 Ajax 技术出现之前,只有浏览器能主动发起计算机之间的通信,而 Ajax 技术出现之后,浏览器提供了 XMLHttpRequest 这个构造函数,使Javascript 能主动发起网络请求。

XML是早期Ajax传递数据所采用的的一种数据格式,HttpRequest是http协议中的请求报文,XMLHttpRequest函数就是能让JS主动发起http请求,从而与服务器之间通过http协议来达到相互通信的目的。

XMLHttpRequest

1.open

JS 要发起一个http请求,首先要new一个 XHR 对象:

var xhr = new XMLHttpRequest();

有了 XHR 对象之后,我们需要调用open方法来“打开”这个XHR对象:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://yapi.demo.qunar.com/mock/63071/helloworld');

第一个参数:method:表示http请求的类型

第二个参数:url:表示的就是http请求的地址

调用了 open 方法之后并不会真正发送请求,而只是启动一个请求以备发送。

2. send

send方法接收一个参数,表示将要发送给服务器的信息,也就是请求报文中的消息体, 消息类型必须为字符串,如果不打算向服务器发送消息,也需要传一个null作为参数

// 创建一个XHR对象
var xhr = new XMLHttpRequest();
// 打开XHR对象,
xhr.open('POST', 'https://www.qsxqd.com/api/play/helloworld');
// 发送http请求
xhr.send('hello');

3. 获取服务器返回的数据

想要获取到服务器返回的数据,我们需要先了解下XHR对象的三个属性:

  1. responseText:保存了服务器返回的数据
  2. status:服务器响应报文的状态码
  3. readyState:表示当前 XHR 对象请求/响应过程的当前活动阶段,这个属性有以下一些取值:
// 创建一个XHR对象
var xhr = new XMLHttpRequest();
console.log('刚刚创建的XHR对象:', xhr.readyState);

// 打开XHR对象,
xhr.open('POST', 'https://www.qsxqd.com/api/play/helloworld');
console.log('调用open函数后的XHR对象:', xhr.readyState);

// 设定XHR对象的onreadystatechange属性
xhr.onreadystatechange = function() {
  console.log('调用send函数后的XHR对象:', xhr.readyState);
}

// 发送http请求
xhr.send('hello');

输出的信息:

刚刚创建的XHR对象:0
调用open函数后的XHR对象:1
调用send函数后的XHR对象:2
调用send函数后的XHR对象:3
调用send函数后的XHR对象:4

其中3表示接收到部分响应数据,4表示已经接收到全部数据

每当XHR对象的readyState属性发生改变时,如果onreadystatechange属性是一个函数,那么浏览器都会运行这个函数

三、实例

实例1: readyState与状态的对应关系

  • 在readyState变为2的时候,在右侧打印出“发送”
  • 在readyState变为3的时候,在右侧打印出“接受”
  • 在readyState变为4的时候,在右侧打印出“完成”
// 创建一个XHR对象
var xhr = new XMLHttpRequest();
console.log('刚刚创建的XHR对象:',xhr.readyState);

//打开XHR对象
xhr.open('POST','https://www.qsxqd.com/api/play/helloworld')
console.log('调用open后的XHR对象:',xhr.readyState)

// 设定XHR对象的onreadystatechange属性
xhr.onreadystatechange = function(){
	console.log('调用send函数后的XHR对象:',xhr.readyState)
  if(xhr.readyState==2)console.log('发送')
  else if(xhr.readyState==3)console.log('接收')
  else if(xhr.readyState==4)console.log('完成')
  
}
//发送消息
xhr.send('hello')

控制台的输出:

刚刚创建的XHR对象:0
调用open后的XHR对象:1
调用send函数后的XHR对象:2
发送
调用send函数后的XHR对象:3
接收
调用send函数后的XHR对象:4
完成

实例2: 向服务器发送请求,并接收到响应

// 创建一个XHR对象
var xhr = new XMLHttpRequest();
console.log('刚刚创建的XHR对象:', xhr.readyState);

xhr.open('POST', 'https://www.qsxqd.com/api/play/helloworld');
console.log('调用open函数后的XHR对象:', xhr.readyState);
// 设定XHR对象的onreadystatechange属性
xhr.onreadystatechange = function() {
console.log('调用send函数后的XHR对象:', xhr.readyState);
  // 浏览器接收完成服务器数据
  if (xhr.readyState === 4) {
    // 响应状态码有效
    if (200 <= xhr.status < 300 || xhr.status === 304) {
      console.log('接收数据:', xhr.responseText);
    }
  }
}
xhr.send('hello');

控制台的输出:

刚刚创建的XHR对象:0
调用open函数后的XHR对象:1
调用send函数后的XHR对象:2
调用send函数后的XHR对象:3
调用send函数后的XHR对象:4
接收数据:hello world!

200 <= xhr.status < 300 || xhr.status === 304:这个条件用来判断响应报文状态码的有效性,只有当状态码处于这个限定条件内,才认定这个请求返回的数据是有意义的

实例3: 向服务器发送消息,接收到响应消息后
1.在父节点里添加一个子节点
2.子节点的id设置为div1-2
3.子节点的innerhtml为服务端返回的响应消息

前端界面如下:

<html>
<head>
</head>
<body>
  <div id='div1'>
    <div id = 'div1-1'> div1-1</div>
  </div>
</body>
</html>
* {
    margin: 0;
    padding: 0;
  }
  #div1 {
    width: 300px;
    height: 300px;
    display: flex;
    justify-content: space-around;
    align-items: center;
    background-color: rgba(0,122,204,0.7);
  }
  #div1 > div{
    width: 100px;
    height: 100px;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: rgba(0,122,204);
  }

运行前:

js代码:

var xhr = new XMLHttpRequest();
console.log('刚刚创建的XHR对象:', xhr.readyState);

xhr.open('POST', 'https://www.qsxqd.com/api/play/helloworld');

xhr.onreadystatechange = function() {

  if (xhr.readyState === 4) {
    if (200 <= xhr.status < 300 || xhr.status === 304) {
      // console.log(xhr.responseText);
      // 在下面补全你的代码吧
      var parentElement= document.getElementById('div1')
      var childElement = document.createElement('div')
      parentElement.appendChild(childElement)
      var result=xhr.responseText
      childElement.innerText=result
      
  	}
  }
}

// 发送http请求
xhr.send('hello');

运行后:


参考:
前端入门:https://www.zhihu.com/question/32314049/answer/713711753
然代码:https://www.qsxqd.com/

以上是关于前端笔记三前后端通信(http协议和Ajax)的主要内容,如果未能解决你的问题,请参考以下文章

前端笔记四前后端通信实例(http协议和Ajax)

前后端分离学习笔记 ---[Vue基础]

网络编程——TCP协议和通信

flask前后端数据通信流程

http协议和tcp协议的区别是什么

tcp协议和udp协议的特点 三次握手四次挥手