前端第十步:AJAX 网络编程与 Axios 库

299 阅读1分钟

[TOC]

AJAX概述

背景

前端的局限性

JavaScript功能强大,但JavaScript能力有限(了解AJAX之前),那就是无法提供API,所有代码都只能满足“单机需求”,无法满足与后端交互数据

这样平时的登录注册无法实现,查询信息无法实现。

这个时候就必须需要一个强大的功能,能通过API获取服务器的数据以及发送数据给数据库

发送请求

基础请求发送方式

  • 地址栏输入地址

  • 特定元素的src属性href属性

  • 表单提交

AJAX出现

Google Suggest

在2005年时,Google Suggest提供了 AJAX方法(Asynchronous JavaScript and XML)

但发展初,它并不是一种正式的技术

AJAX作用

为浏览器提供一套API,可以通过JavaScript直接调用,从而能实现前端向后端请求与响应

AJAX的X——XML:早期客服端与服务端之间传递数据时所用的数据格式

AJAX使用

体验如何操作AJAX

通过JQuery封装的方法

<script src="js/jquery-1.12.4.min.js">   ",       type: "GET",       dataType: "json",       data: {"id": 1},       success: function (data) {         // 使用请求成功的数据         console.log(data);       }     })   

通过原生JS

// 1.创建一个 XMLHttpRequest 类型的对象  --- 相当于打开了一个浏览器
var xhr = new XMLHttpRequest();
// 2.打开一个与网址之间的连接  --- 相当于在地址栏输入网址
xhr.open("GET","https://jsonplaceholder.typicode.com/users");
// 3.通过连接发送一次请求 --- 相当于点击回车或者超链接
xhr.send(null);
// 4.指定 xhr 状态变化事件处理函数   --- 相当于处理网页呈现后的操作
xhr.onreadystatechange = function () {
  // 通过判断 xhr 的 readyState ,确定此次请求是否完成
  if (this.readyState === 4) {
    console.log(this.responseText)
  }
}

Ajax请求步骤

  1. 创建XMLHttpRequest对象
  2. 打开一个(网页之间的)连接
  3. 发送
  4. 指定返回状态变化事件处理函数

原生Ajax

详讲

请求步骤

  1. 创建XMLHttpRequest对象
  2. 打开一个(网页之间的)连接
  3. 发送
  4. 指定返回状态变化事件处理函数

XMLHttpRequest内置对象

创建XMLHttpRequest对象

所有Ajax操作都会使用这一个内置对象

let xhr = new XMLHttpRequest();

// IE6 兼容问题
var xhr = new ActiveObject("Microsofft.XMLHTTP");
// 兼容性写法
var xhr = null;
if(window.XMLHttpRequest
   xhr = new XMLHttpRequest();
else
   xhr = new ActiveXObject("Microsoft.XMLHTTP");

请求方式及目标地址:open方法

语法: xhr.open( method, url );

​ method 为传输方法,一般有:[GET]、[POST]、[PUT]、[DELETE]等,但实际编程中只用post和get

​ url 为发送请求URL地址,数据类型为String

注意:该方法必须写在send方法前面

设置请求头:setRequestHeader方法

语法:xhr.setRequestHeader( header, value );

​ header:一般设置"Content-Type",传输数据类型,一般为服务器需要我们传送的数据类型

​ value:具体的数据类型,常用:"application/x-www-form-urlencoded"和"application/json"

注意:该方法必须写在open后面send前面

设置请求中的数据体:send方法

语法:xhr.send(body)

​ body为请求时发送的数据体

注意:该方法必须写在open方法后面

返回数据中的readyState属性

说明:readyState 属性返回一个 XMLHttpRequest 代理当前所处的状态,由于 readystatechange 事件是 在 xhr 对象状态变化时触发

ready State值状态描述说明
0UNSEND代理XHR被创建,但未调用open方法
1OPENEDopen方法已经被调用,并且已经创建连接
2HEADERS_RECEIVEDsend方法已经被调用,并且已经可以获取状态行和响应头
3LOADING响应体下载中, responseText 属性可能已经包含部分数据
4DONE响应体下载完成,可以直接使用responseText

0-4表示返回请求的5个状态

事件处理

建议:一般事件处理都是在后端返回所有数据后,也就是 readyState=4

方法:

xhr.onreadystatechange = function() {
	if (this,readyState === 4) {
		// 后续操作
	}
}

不同的传输方式对应不同的方法

post传输方式

1、必须设置请求头

xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

2、能通过send设置传参

xhr.send("name=harry&age=19");

get传输方式

1、不用设置请求头

2、get方法无法使用send传参,只能通过网址传输

3、请求还是要通过send传输

同步与异步

同步:等待上一个事件完成后才进行下一步操作

异步:上一个事件还在处理时,不等待直接进行下一步操作

Ajax中的同步与异步

xhr.open()方法可以设置第三个参数,其作用为本次请求是同步还是异步方式执行

数据类型为布尔型默认值为true,表示是异步执行,若是要进行同步执行则设置为false

采用同步方式执行,则代码会卡死在 xhr.send() 这一步

使用建议

为了让这个事件一定触发,在发送请求 send() 之前,一定是先注册 readystatechange

正常开发时,不建议使用同步模式

响应数据格式

XML

一种数据描述手段,已经被淘汰

<?xml verson="1.0" encoding="utf-8" ?>
<booklist>
  <book>
    <name>三国演义</name>
    <author>罗贯中</author>
    <cate>古典名著</cate>
  </book>
  <book>
    <name>西游记</name>
    <author>吴承恩</author>
    <cate>古典名著</cate>
  </book>
  <book>
    <name>红楼梦</name>
    <author>曹雪芹</author>
    <cate>古典名著</cate>
  </book>
</booklist>

前端淘汰原因:

  1. 元数据占用数据量比较大(数据利用率低),不利于大量数据网络传输

  2. js内部解析时,方法比较复杂

JSON

JavaScript Object Notation,JavaScript 对象表示法

一种数据描述手段,类似于JS中的对象

现在前后端传输都是用 JSON 格式交互数据

注意

无论是已经被淘汰的XML还是现在常用的JSON都是一种数据协议,与AJAX没有必然联系

不管服务端是采用 XML 或 JSON ,本质上都是将数据返回给客户端

JSON Server

json-server 是一个 Node 模块,我们可以使用它快速的搭建一个 web 服务器

配置网址:github.com/typicode/js…

使用步骤:

  1. 在命令窗口通过node 下载json-server插件,下载代码为:npm install -g json-server

  2. 在json所在位置使用控制终端,输入 json-server --watch 文件名.json

  3. 服务器驱动的json文件书写格式

{
    "路径地址":{"属性名":"属性值"},
    "下一个路径":[
        {"属性名":"属性值"},
        {"属性名":"属性值"},
        {"属性名":"属性值"},
        {"属性名":"属性值"}
    ]
}
  1. 服务器驱动成功

原生AJAX具体用法

GET请求

通常在一次 GET 请求过程中,参数传递都是通过 URL 地址中的 ? 参数传递

get请求无需设置请求头

无需设置响应体,可以传输 null 或者不传

POST请求

POST请求过程都是采用请求体承载交互的数据

必须设置请求头的“Content-Type”,以便于服务端接受对应的数据体

需要提交到服务器的数据可以通过send方法传参

渲染响应数据

通过dom节点操作将客户需要的数据渲染上去

封装AJAX库

一般用第三方的AJAX库,因为第三方封装的库比自己封装的要更加严谨

JQuery的AJAX

JQuery有一套完整的AJAX封装

注意:ajax技术包括 DOM、XML、JavaScript

$.ajax()方法

常用参数

参数名说明例子
url请求地址"www.baidu.com"
type请求方法,默认为 "get"get、post、delete
dataType服务器响应数据类型类型
contentTyep请求体内容类型application/x-www-form-urlencoded
data传递到服务器的数据类型
timeout请求超时时间
beforeSend请求发起之前触发
success请求成功后触发
error请求失败触发
complete请求完成后触发(无论请求成功与否)
$.ajax({
  url: "http://localhost:3000/posts",
  type: "post",
  contentType:"application/json",
  dataType: "json",
  data: JSON.stringify( {"id": 2}),
  beforeSend: function (xhr) {
    console.log("before send");
  },
  success: function (data) {
    console.log(data);
  },
  error: function (xhr) {
    console.log(xhr);
  },
  complete: function (xhr) {
    console.log(xhr);
  }
});

GET请求

通过ajax自己封装的get方法

语法: $.get(url,data,callback)

$.get("http://local:3000/test",
{
	"id":1,
	name:"Tom"
},
function(data){
	// data为回调数据
    console.log(data);
}
)

POST请求

通过ajax自己封装的post方法

语法: $.post(url,data,callback)

$.post("http://local:3000/test",
{
	"id":1,
	name:"Tom"
},
function(data){
	// data为回调数据
    console.log(data);
}
)

其他方式请求

put:

$.ajax({
      url: "http://localhost:3000/comments/4",
      type: "put",
      dataType: "json",
      data: {"content": "good", "postId": 2},
      success: function (data) {
        console.log(data)
      }
    })

delete:

$.ajax({
      url: "http://localhost:3000/comments/5",
      type: "delete",
      success: function (data) {
        console.log(data)
      }
    })

设置ajax默认属性:$.ajaxSetup方法

$.ajaxSetup({
    url:"localhost:3000",
    type:"post",
    contentType:"application/json",
    dataType:"json"
});
//设置ajax默认属性,方便以后调用

Ajax升级——Axios

注意:jQuery1.12.X没有Axios库,只有ajax

引用方法:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<!-- 或者把网页上面的axios.min.js下载下来,直接本地调用 -->

Axios API

通过axios方法相关配置来传递创建请求

语法:axios( url , config ) 或者 axios( config )

​ url一般为请求地址

​ config为请求配置

// 配置示例
{
    method:"post",
    url   :"localhost:8080/login",
    headers:{
        contentType:"application/json"
    }
    dataType :"json",
    data: JSON.stringify({
        "name":"Tom",
        "age":20
    })
}
常用配置项说明
url用于请求的服务器地址,必须写
method创建请求时用的方法
baseURL传递相对URL前缀,会自动添加在url前面
headers自定义请求头
params将参数放置在地址栏,随着地址栏进行请求
data作为请求主体时被发送的数据
timeout指定请求超时的毫秒数(0表示无超时设置)
responseType表示服务器响应的数据类型,默认为"json"

后续请求成功的方法: then方法

请求成功后,axios有自己封装好的方法:then方法

axios().then(function(response){
    // 正常请求成功后,响应信息对象 response
    // response 可以简写为 res
    // 后续数据渲染或者其他网页操作都是靠response中的数据
})

后续请求失败的方法:catch方法

若请求失败,axios有自己封装好的方法:then方法

axios().then().catch(function(error){
    // 请求出错时,error为捕获出错对象
    // error 可以简写成 err
})

全局配置设置

可以指定引用的axios的默认设置,便于后续操作

axios.defaults.baseURL = "https://localhost:8080";
axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";

拦截器

请求或者响应在 then 及 catch 处理前拦截

// 请求前后的拦截器(请求拦截器)
axios.interceptors.request.use( function(config){
    // 发送请求之前做什么
    return config;
} , function(error){
    // 请求出错时做什么
    return Promise.reject(error);
} )
// 响应前后的拦截器(响应拦截器)
axios.interceptors.response.use( function(response){
    // 接收到响应数据后做啥
    return response;
} , function(error){
    // 响应数据出错后做啥
    return Promise,reject(error);
} )

快速请求方法

get的快速请求方法:axios.get( url [ , config ] )

post的快速请求方法:axios.post( url [ , config ] )

delete的快速请求方法:axios.delete( url [ , config ] )

put的快速请求方法: axios.put( url [ , config ] )

// 示例:get快速请求
axios.get("/post",{ 
    params:{ id : 1 },
    baseURL:"localhost:3000"
})
.then(function(res){
    console.log(res.data);
})
.catch(function(err){
    console.log(err);
});

// 示例:post快速请求
axios.post("/post",{
    headers:{
        contentType:"applaction/json"
    },
    baseURL:"localhost:3000",
    responseType:"json",
    data:JSON.stringify({id:1})
})
.then(function(res){
    console.log(res.data);
})
.catch(function(err){
    console.log(err);
});

原生JS中XMLHttpRequest2.0

内置的onload方法

触发时间:readyState = 4,也就是说在请求结束后

xhr.onload = function(){
    console.log(this.readyState);
};

内置的onprogress方法

触发时间: readyState = 3 ,也就是说在获取响应时,不是获取完整响应时

xhr.onprogress = function(e){
    console.log(this.readyState);
    // e.loaded 为接收到数据个数
    console.log(e.loaded);
    // e.total 为接受数据的总个数
    console.log(e.total);
}

内置的responseType属性

该属性是设置请求数据类型

注意:该方法要写在open方法初始化之后,send方法之前

xhr.responseType = "json";

跨域和模板引擎应用

同源

什么是同源

同源指在同一服务器

如何判定:

服务器地址一样,便是同源;后面请求地址与 是否同源无关系

服务器地址由三部分构成

说明例子
传输协议http、https
域名/IP地址www.lagou.com 、 14.215.177.38
端口号:8080 、 :4200

注意: localhost 与 127.0.0.1 同源

同源策略

在同源情况下,Ajax能在同源中进行正常访问,但是无法跨域访问

这是一种浏览器的安全策略

不同源地址请求称之为跨域请求

跨域解决方案

JSONP

原理:在客户端接用script标签请求服务器的一个地址

  • JSONP (JSON with Padding),是一种借用script标签发送跨域请求的技巧
  • 服务器响应后,会返回一段某个全局函数调用的JavaScript脚本
  • 在调用函数中,原本需要返回给客户端的数据通过参数传递给这个函数
  • 之后客户端的函数就可以通过参数得到原本服务器返回的数据
// 动态生成 script 标签
var script= document.createElement("script");
script.src = "localhost:8888/data.php?callback=fun"
// callback意思是回调函数
// 添加到head标签内部
var head = document.getElementsByTagName("head")[0];
head.appendChild(script);

// 客户端定义回调函数
function fun( data ) {
    console.log(data);
}

示意:服务器的响应

注意:JSONP只能发送 GET 请求

​ JSONP使用的是 script 标签 ,与 AJAX、XMLHttpRequest 没有任何关系

JQuery中封装的JSONP

jQuery中使用JSONP 方式 仅仅是 设置 dataType 为 jsonp 即可

$.ajax({
  url: "https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web",
  type: "GET",
  dataType: "jsonp",
  jsonp: "cb",    //设置回调函数的参数名称(必须与后台接口的回调函数参数名保持一致)
  jsonpCallback: "abc", // 重命名回调函数
  data: {"wd": "ajax"},
  success: function (data) {
    console.log(data)
  }
})

CORS

全称: Cross Origin Resource Share,跨域资源共享

该方法无需客户端做出任何变化,只是在请求的服务器响应时添加一个 Access-Control-Allow-Origin 的响应头,表示该资源是否允许指定域请求。

Access-Control-Allow-Origin的值为

* 表示允许任意资源访问,不安全

http:// fool.com 允许指定的源访问

<?php
    header("Access-Control-Allow-Origin:http://foo.example");
	header("Access-Control-Allow-Origin:*");
?>

模板引擎

作用:减少字符串拼接,便于开发

模板中解析json,之后跟html内容拼接

模板例子:artTemplate

一种简约、快捷的模板引擎

网址:github.com/aui/artTemp… 中文使用文档:aui.github.io/art-templat…

语法规则

  • 原始语法
语法说明
<% %>模板逻辑表达式,包括 if、for 等逻辑语句
<%= %>输出表达式
  • 标准语法
语法说明
{{ if user }} {{/if}}模板逻辑表达式,包括 if、for 等逻辑语句
{{ user.name }}输出表达式

使用规则

在调用之前引入模板引擎,并在引擎下通过 script 标签写入模板

script 标签

原始版

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>test02</title>
        <script src="js/template-native.js"></script>
        <script id="test" type="text/html">
<!-- 定义模板 -->
            <% if (name%2==0){ %>
                <h2><%= name %></h2>
            <%}%>
        </script>
    </head>
    <body>
        <div id="box">

        </div>
        <script src="js/jquery-1.12.4.min.js"></script>
        <script>
            for(let i = 0 ;i<20;i++)
                $("#box").append(template("test",{name:i}));
        </script>
    </body>
</html>

标准版

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>test02</title>
        <script src="https://unpkg.com/art-template/lib/template-web.js"></script>
        <script id="test" type="text/html">
            <!-- 定义模板 -->
            {{if name%2==0}}
                <h2>{{name}}</h2>
            {{/if}}
        </script>
    </head>
    <body>
        <div id="box">

        </div>
        <script src="js/jquery-1.12.4.min.js"></script>
        <script>
            for(let i = 0 ;i<20;i++)
                $("#box").append(template("test",{name:i}));
        </script>
    </body>
</html>