StepByStep前端科普系列(006)-前端网络请求那丢丢点儿的事

159 阅读7分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情

前端请求后端接口主要有哪些方式呢?

  1. 刷新页面:最直接但是最体验最差的一种方式

  2. form表单:会触发页面跳转,无法实现页内重复请求

  3. iframe:比较消耗性能,且控制成本过高

  4. Ajax - 使用XMLHttpRequest对象进行异步请求,极大的提高了用户体验,实现了页内请求

  5. Fetch - Ajax的替代者,浏览器内置方法,封装了Promise机制,优化了异步问题

  6. jQuery - 一种前端框架,封装了数据请求模块,但体积较大

  7. axios、request等众多第三方开源库:对原生方法的二次封装,各有优劣势,百家争鸣


一、Form 表单

<form action='http://www.abc.com/postValue' method='post'>
    <input type='text' name='username' />
    <input type='password' name='password'/>
    <input type='submit' value='登陆'/>
</form>

在Form标签中添加Action(提交的地址)和method(post、get)且有一个submit按钮 <input type=’submit’> 就可以进行数据的提交,每一个input标签都需要有一个name属性,才能进行提交。

当点击登陆时,向服务端发送的数据是:username=username&password=password

The FormData interface provides a way to construct a set of key/value pairs representing form fields and their values, which can be sent using the fetch() or XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to "multipart/form-data".

表单提交原理:

1.表单提交时表单内容会被浏览器封装为HTTP请求包,里面包含了所有表单元素的name属性值和value属性的值,形式为name=value。

2.该HTTP请求包被webserver获取后会被解析并封装成一个Request对象,Request对象里有一个Parameters集合专门用来存放所有的表单元素键值对,这里的parameters即Firefox的HttpRequester插件Parameters。

3.每个表单元素名值对被封装成一个Parameter,而Parameter其实就是一个Map,所以你的Server里就可以用request.getParameter(name)获取其value了。

4.如果用get方式提交表单,会在地址栏显示 param=value 这种形式,比如说提交路径是http://localhost/MyDemo/testAction.do?id=test&status=insert   get是默认的提交方式

5.然后通过Firefox的HttpRequester插件(参数可以写入Content to Send、Headers、Parameters传递给后端),发起一个http url请求。

这种交互方式的缺陷是显而易见的,任何和服务器的交互都是需要刷新页面的,造成的问题就是用户体验很差

二、AJAX (Asynchronous JavaScript and XML)

1999年,微软公司发布IE5,第一次引入新功能:允许javascript脚本向服务器发起HTTP请求。这个功能当时并没有引起注意,直到2004年Gmail发布和2005年Google Map发布,才引起广泛重视。2005年2月,ajax这个词第一次正式提出,指围绕这个功能进行开发的一整套做法。从此,ajax成为脚本发起HTTP通信的代名词,W3C也在2006年发布了它的国际标准。

AJAX可以认为是JavaScript脚本发起HTTP通信的代名词。这里面 js 部分就是XHR对象。XMLHttpRequest是一个浏览器内置对象。

// 1. 创建一个 new XMLHttpRequest 对象 
let xhr = new XMLHttpRequest(); 

// 2. 配置它:从 URL /article/.../load GET-request
xhr.open('GET', '/article/xmlhttprequest/example/load'); 

// 3. 通过网络发送请求 
xhr.send(); 

// 4. 当接收到响应后,将调用此函数 
xhr.onload = function() {
      if (xhr.status != 200) { // 分析响应的 HTTP 状态
        alert(`Error ${xhr.status}: ${xhr.statusText}`); // 例如 404: Not Found
        } else { // 显示结果
        alert(`Done, got ${xhr.response.length} bytes`); // response 是服务器响应
        }
     };

xhr.onprogress = function(event) {
    if (event.lengthComputable) {
        alert(`Received ${event.loaded} of ${event.total} bytes`);
    } else {
        alert(`Received ${event.loaded} bytes`); // 没有 Content-Length
        }
    };
    
xhr.onerror = function() {
    alert("Request failed");
};

总结:1。创建AJAX对象;2.发出HTTP请求;3.接收服务器传回的数据;4.更新网页数据。概括起来就是一句话,ajax通过原生XMLHttpRequest对象发出HTTP请求,得到服务器返回的数据后,再进行处理。通过设置给AJAX引擎的回调函数获得服务器响应数据,使用JavaScript在指定位置,显示响应数据,从而局部修改页面数据,这样就达到局部刷新目的。

与之对应的全局刷新,用户在某个标签页输入 URL 并回车后,或者在打开的网页上点击重载时(Reload this page),浏览器主进程会新开一个网络线程,发起 HTTP 请求。

优点:

  • 不重新加载页面的情况下更新网页
  • 在页面已加载后从服务器请求/接收数据
  • 在后台向服务器发送数据

缺点:使用起来也比较繁琐,需要设置很多值


三、jQuery

为了更快捷的操作DOM,并且规避了一些浏览器兼容问题,就产生了jQuery。它里面的AJAX请求也兼容了各浏览器,可以有简单易用的方法$.get$.post。简单点说,就是对XMLHttpRequest对象的封装。对原生XHR的封装,做了兼容处理,简化了使用。增加了对JSONP的支持,可以简单处理部分跨域。


四、Fetch

Fetch是浏览器内置API,在浏览器环境中,可以通过顶层对象window获取。fetch() 是一个全局方法,提供一种简单,合理的方式跨网络获取资源。它的请求是基于 Promise 的。Fetch 提供了对 Request 和 Response (以及其他与网络请求有关的)对象的通用定义。

image.png

Fetch 与 XMLHttpRequest基本相同,但有三个主要差异

fetch()的功能与 XMLHttpRequest 基本相同,但有三个主要的差异。

(1)fetch()使用 Promise,不使用回调函数,因此大大简化了写法,写起来更简洁。

(2)fetch()采用模块化设计,API 分散在多个对象上(Response 对象、Request 对象、Headers 对象),更合理一些;相比之下,XMLHttpRequest 的 API 设计并不是很好,输入、输出、状态都在同一个接口管理,容易写出非常混乱的代码。

(3)fetch()通过数据流(Stream 对象)处理数据,可以分块读取,有利于提高网站性能表现,减少内存占用,对于请求大文件或者网速慢的场景相当有用。XMLHTTPRequest 对象不支持数据流,所有的数据必须放在缓存里,不支持分块读取,必须等待全部拿到后,再一次性吐出来。

// `fetch()`接受一个 URL 字符串作为参数,默认向该网址发出 GET 请求,
// 返回一个 Promise 对象。
    fetch(url)
      .then(...)
      .catch(...)
  
  
// 示例
fetch('https://api.github.com/users/ruanyf')
  .then(response => response.json())
  .then(json => console.log(json))
  .catch(err => console.log('Request Failed', err)); 


五、axios

axios是基于 Promise 的 ajax 封装库,也是前端目前最流行的 ajax 请求库。axios是基于Promise对原生的XMLHttpRequest进行了全面的封装,使用的方式也很优雅。并且也提供了在node环境下的支持。它本质也是对原生XMLHttpRequest的封装,只不过它是Promise的实现版本,符合最新的ES规范。

引入方式一:

首先通过npm进行安装 npm install axios --save

// 代码中引入
import axios from 'axios'

引入方式二:

//使用 CDN 来引入 axios

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
使用 axios 创建请求:

基于 Axios,你可以使用  GET  和  POST  来向服务端请求数据和发送数据。

GET

POST

Axios  返回一个 “Promise”。如果你对 Promise 比较熟悉的话,你应该知道用 Promise 可以用来执行并行请求。这里你就可以用 axios 在同一时间运行多个并行请求。


六、Angular HttpClient

Angular 有它自己的和 Angular 应用一起运行的 HTTP 模块。它使用到了  RxJS  库来处理异步请求,同时还提供了许多用来执行 HTTP 请求的选择。


参考文献:

前端如何发起http请求及各方法的优缺点

用 JavaScript 发起 HTTP 请求的几种方法

Fetch API 教程

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天,点击查看活动详情