Ajax笔记

2020-08-21  本文已影响0人  Scincyc

1. Ajax 基础

1.1 传统网站中存在的问题

1.2 Ajax 概述

Ajax:标准读音 [ˈeɪˌdʒæks] ,中文音译:阿贾克斯

它是浏览器提供的一套方法,可以实现页面无刷新更新数据,提高用户浏览网站应用的体验

1.3 Ajax 的应用场景

1.4 Ajax 的运行环境

Ajax 技术需要运行在网站环境中才能生效,当前课程会使用Node创建的服务器作为网站服务器

2. Ajax 运行原理及实现

2.1 Ajax 运行原理

Ajax 相当于浏览器发送请求与接收响应的代理人,以实现在不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验

2.2 Ajax 的实现步骤

//1. 创建 Ajax 对象
var xhr = new XMLHttpRequest();
//2.  告诉 Ajax 请求后端的地址以及请求方式
 xhr.open('get', 'http://www.example.com');
//3.  发送请求
 xhr.send();
//4.  获取服务器端给与客户端的响应数据
 xhr.onload = function () {
     console.log(xhr.responseText);
 }

2.3 服务器端响应的数据格式

在真实的项目中,服务器端大多数情况下会以 JSON 对象作为响应数据的格式。当客户端拿到响应数据时,会被转换为对象字符串,所以要将 对象字符串转换为JSON 数据,再和 HTML 字符串进行拼接,然后将拼接的结果展示在页面中

注意:在 http 请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输

 JSON.parse() // 将 json 字符串转换为json对象
JSON.stringify() // 将json对象转换为json字符串

get start

//客户端html文件
<script type="text/javascript">
        // 1.创建ajax对象
        var xhr = new XMLHttpRequest();
        // 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
        // 1)请求方式 2)请求地址
        xhr.open('get', 'http://localhost:3000/responseData');
        // 3.发送请求
        xhr.send();
        // 4.获取服务器端响应到客户端的数据
        xhr.onload = function (){
            // console.log(typeof xhr.responseText)
            // 将JSON字符串转换为JSON对象
            var responseText = JSON.parse(xhr.responseText);
            // 测试:在控制台输出处理结果
            console.log(responseText,responseText.name)
        }
</script>
// 服务器端app.js

// 引入express框架
const express = require('express');
// 路径处理模块
const path = require('path');
// 创建web服务器
const app = express();
// 静态资源访问服务功能
app.use(express.static(path.join(__dirname, 'public')));
// 返回响应
app.get('/responseData', (req, res) => {
    res.send({"name": "zs"});
});

2.4 请求参数传递

传统网站表单提交

 <form method="get" action="http://www.example.com">
     <input type="text" name="username"/>
     <input type="password" name="password">
 </form>
 <!–- http://www.example.com?username=zhangsan&password=123456 -->

2.4.1 GET 请求方式

xhr.open('get', 'http://www.example.com?name=zhangsan&age=20');

get start

//1. 客户端文件

var xhr = new XMLHttpRequest();
// get方式
var params = 'name=zhangsan&age=20';
xhr.open('get', 'http://www.example.com?'+params);
xhr.send();
// 获取服务器端响应到客户端
xhr.onload = function (){
    var responseText = JSON.parse(xhr.responseText);
    console.log(responseText);
}
//结果:{name: zhangsan, age: 20}
//2. 服务器端app.js

const express = require('express');
const path = require('path');
// 创建web服务器
const app = express();
// 静态资源访问服务功能
app.use(express.static(path.join(__dirname, 'public')));
// 返回响应
app.get('/get', (req, res) => {
    res.send(req.query);
});

2.4.2 POST 请求方式

xhr.open('post', 'http://localhost:3000/post');
//设置报文头(post请求必须要设置)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//设置报文体
xhr.send('name=zhangsan&age=20');

请求参数的格式:

  1. application/x-www-form-urlencoded

    name=zhangsan&age=20&sex=男
    
  2. application/json

     {name: 'zhangsan', age: '20', sex: '男'}
    

    在请求头中指定 Content-Type 属性的值是 application/json,告诉服务器端当前请求参数的格式是 json

     JSON.stringify() // 将json对象转换为json字符串
    

注意:get 请求是不能提交 json 对象数据格式的,传统网站的表单提交也是不支持 json 对象数据格式的

get start

//1. 客户端文件
var xhr = new XMLHttpRequest();
xhr.open('post', 'http://localhost:3000/post');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('name=zhangsan&age=20');
// 获取服务器端响应的数据
xhr.onload = function () {
    var responseText = JSON.parse(xhr.responseText);
    console.log(responseText);
}
//结果:{name: zhangsan, age: 20}
//2. 服务器端app.js

const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
//服务端配置具体的格式
app.use(bodyParser.urlencoded());

const app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.post('/post', (req, res) => {
    // 需要引入body-parser模块
    res.send(req.body);
});
//1.客户端
var xhr = new XMLHttpRequest();
xhr.open('post', 'http://localhost:3000/json');
xhr.setRequestHeader('Content-Type', 'application/json');
// JSON.stringify() 将json对象转换为json字符串
// 3.发送请求 (参数必须为字符串)
xhr.send(JSON.stringify({name: 'lisi', age:50}));
xhr.onload = function (){
    console.log(xhr.responseText)
}
//结果:{"name":"lisi","age":50}
//2. 服务器端app.js

const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
//服务端配置具体的格式
app.use(bodyParser.json());

const app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.post('/post', (req, res) => {
    // 需要引入body-parser模块
    res.send(req.body);
});

2.5 获取服务器端的响应

2.5.1 Ajax 状态码

在创建ajax对象,配置ajax对象,发送请求,以及接收完服务器端响应数据,这个过程中的每一个步骤都会对应一个数值,这个数值就是ajax状态码

0:请求未初始化(还没有调用open())
1:请求已经建立,但是还没有发送(还没有调用send())
2:请求已经发送
3:请求正在处理中,通常响应中已经有部分数据可以用了
4:响应已经完成,可以获取并使用服务器的响应了

 xhr.readyState // 获取Ajax状态码

2.5.2 onreadystatechange 事件

当 Ajax 状态码发生变化时将自动触发该事件

在事件处理函数中可以获取 Ajax 状态码并对其进行判断,当状态码为 4 时就可以通过 xhr.responseText 获取服务器端的响应数据了

 // 当Ajax状态码发生变化时
 xhr.onreadystatechange = function () {
     // 判断当Ajax状态码为4时
     if (xhr.readyState == 4) {
         // 获取服务器端的响应数据
         console.log(xhr.responseText);
     }
 }

get start

// 1.客户端
var xhr = new XMLHttpRequest();
// 0 已经创建了ajax对象 但是还没有对ajax对象进行配置
console.log(xhr.readyState);
xhr.open('get', 'http://localhost:3000/readystate');
// 1 已经对ajax对象进行配置 但是还没有发送请求
console.log(xhr.readyState);

// 当ajax状态码发生变化的时候出发
xhr.onreadystatechange = function() {
    // 2 请求已经发送了
    // 3 已经接收到服务器端的部分数据了
    // 4 服务器端的响应数据已经接收完成
    console.log(xhr.readyState);
    // 对ajax状态码进行判断 如果状态码的值为4就代表数据已经接收完成了
    if (xhr.readyState == 4) {
        console.log(xhr.responseText);
    }
} 

xhr.send();
//0 1 2 3 4 hello
//2. 服务器端app.js
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.get('/get', (req, res) => {
    res.send('hello');
});

2.5.3 获取服务器端的响应

两种获取服务器端响应方式的区别

区别描述 onload事件 onreadystatechange事件
是否兼容IE低版本 不兼容 兼容
是否需要判断Ajax状态码 不需要 需要
被调用次数 一次 多次

2.6 Ajax 错误处理

  1. 网络畅通,服务器端能接收到请求,服务器端返回的结果不是预期结果。
    可以判断服务器端返回的状态码,分别进行处理。xhr.status 获取http状态码

  2. 网络畅通,服务器端没有接收到请求,返回404状态码。
    检查请求地址是否错误

  3. 网络畅通,服务器端能接收到请求,服务器端返回500状态码。
    服务器端错误,找后端程序员进行沟通

  4. 网络中断,请求无法发送到服务器端。
    会触发xhr对象下面的onerror事件,在onerror事件处理函数中对错误进行处理

get start

var btn = document.getElementById('btn');

btn.onclick = function () {
    // 1.创建ajax对象
    var xhr = new XMLHttpRequest();
    // 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
    // 1)请求方式 2)请求地址
    xhr.open('get', 'http://localhost:3000/error');//请求地址错误404
    // 3.发送请求
    xhr.send();
    // 4.获取服务器端响应到客户端的数据
    xhr.onload = function (){
        // xhr.status 获取http状态码
        console.log(xhr.responseText);

        if (xhr.status == 400) {
            alert('请求出错')
        }
    }
    // 当网络中断时会触发onerrr事件
    xhr.onerror = function () {
        alert('网络中断, 无法发送Ajax请求')
    }
}

// Ajax状态码: 表示Ajax请求的过程状态 ajax对象返回的
// Http状态码: 表示请求的处理结果 是服务器端返回的
//服务器端
...
app.get('/error', (req, res) => {
    //console.log(abc);语法错误500
    res.status(400).send('not ok');
});

2.7 低版本 IE 浏览器的缓存问题

问题:在低版本的 IE 浏览器中,Ajax 请求有严重的缓存问题,即在请求地址不发生变化的情况下,只有第一次请求会真正发送到服务器端,后续的请求都会从浏览器的缓存中获取结果。即使服务器端的数据更新了,客户端依然拿到的是缓存中的旧数据

解决方案:在请求地址的后面加请求参数,保证每一次请求的请求参数的值不相同

 xhr.open('get', 'http://www.example.com?t=' + Math.random());

get start

var btn = document.getElementById('btn');

btn.onclick = function () {
    var xhr = new XMLHttpRequest();
    // 请求参数的值不相同
    xhr.open('get', 'http://localhost:3000/cache?t=' + Math.random());
    xhr.send();
    
    xhr.onreadystatechange = function (){
        // 数据已经接收完成并响应正常
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert(xhr.responseText);
        }
    }
}
const fs = require('fs');
...
app.get('/cache', (req, res) => {
    fs.readFile('./test.txt', (err, result) => {
        res.send(result);
    });
});

3. Ajax 异步编程

3.1 同步异步概述

3.1.1 同步

上一行代码执行完成后,才能执行下一行代码,即代码逐行执行

3.1.2 异步

异步代码虽然需要花费时间去执行,但程序不会等待异步代码执行完成后再继续执行后续代码,而是直接执行后续代码,当后续代码执行完成后再回头看异步代码是否返回结果,如果已有返回结果,再调用事先准备好的回调函数处理异步代码执行的结果

 console.log('before');
 setTimeout(
    () => { console.log('last');
 }, 2000);
 console.log('after');

3.2 Ajax 封装

问题:发送一次请求代码过多,发送多次请求代码冗余且重复

解决方案:将请求代码封装到函数中,发请求时调用函数即可

 ajax({ 
     type: 'get',
     url: 'http://www.example.com',
     success: function (data) { 
         console.log(data);
     }
 })

请求参数要考虑的问题

1.请求参数位置的问题

将请求参数传递到ajax函数内部, 在函数内部根据请求方式的不同将请求参数放置在不同的位置

2.请求参数格式的问题

​ name=zhangsan&age=20

​ {name: 'zhangsan', age: 20}

​ 1).传递对象数据类型对于函数的调用者更加友好

​ 2).在函数内部对象数据类型转换为字符串数据类型更加方便

// ajax函数的封装
function ajax(options) {
    // 默认参数
    var defaults = {
        type: 'get',
        url: '',
        data: {},
        header: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        success: function () { },
        error: function () { }
    }
    // 使用defaults的属性覆盖options的属性
    Object.assign(defaults, options);

    // 参数的格式转换
    var params = '';
    for (var attr in defaults.data) {
        params += attr + '=' + defaults.data[attr] + '&';
    }
    // 最后一个&字符截去
    params = params.substr(0, params.length - 1);
    console.log(params);



    var xhr = new XMLHttpRequest();

    // 请求类型不同 参数位置不同
    if (defaults.type == 'get') {
        xhr.open(defaults.type, defaults.url + '?' + params);
        xhr.send();
    } else if (defaults.type == 'post') {
        // 用户传递的参数类型
        var contentType = defaults.header['Content-Type'];
        xhr.open(defaults.type, defaults.url);
        xhr.setRequestHeader('Content-Type', contentType)
        // 请求参数类型不同
        if (contentType == 'application/json') {
            xhr.send(JSON.stringify(defaults.data));
        } else {
            xhr.send(params);
        }
    }

    // 响应处理函数
    xhr.onload = function () {
        // 服务器端的响应类型
        var contentType = xhr.getResponseHeader('Content-Type');
        // 将返回的对象字符串转换为对象
        var responseText = xhr.responseText;
        console.log('contentType', contentType);
        if (contentType.includes('application/json')) {
            responseText = JSON.parse(responseText);
        }

        if (xhr.status == 200) {
            options.success(responseText);
        } else {
            options.error(responseText);
        }
    }
}
// 配置ajax函数的参数
ajax({
    type: 'get',
    url: 'http://localhost:3000/responseData',
    data: {
        name: 'zhangsan',
        age: 18
    },
    header: {
        'Content-Type': 'application/json'
    },
    success: function (data) {
        console.log(data + '获取成功');
    },
    error: function (data) {
        console.log(data + '获取失败');
    }
});
//输出:
//name=zhangsan&age=18
//contentType application/json; charset=utf-8
//[object Object]获取成功
...
app.get('/responseData', (req, res) => {
    res.send({"name": "zs"});
});

4. FormData

4.1 FormData对象的作用

  1. 模拟HTML表单,相当于将HTML表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式
  2. 异步上传二进制文件

4.2 FormData对象的使用

<!-- 1.创建表单对象 -->
    <form id="form">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="text" id="btn" value="提交"> 
    </form>
    <script>
        //2. 获取表单对象
        var form = document.getElementById('form');
        var btn = document.getElementById('btn');
        btn.onclick = function() {
            // 3.将 HTML 表单转化为 formData 对象
            var param = new FormData(form);
            var xhr = new XMLHttpRequest();
            xhr.open('post', 'http://localhost:3000/formData');
            // 4.提交表单对象 到服务器端(post)
            xhr.send(param);
        }
        // 5.监听xhr对象下面的onload,接收响应数据
        xhr.onload = function() {
            if(xhr.status == 200) {
                // 响应正常
                console.log(xhr.responseText);
            }
        }
        // 6.异常处理
        xhr.onerror = function() {
            console.log("响应异常");
        }

    </script>

4.2 formidable模块

// 服务器端app.js
const formidable = require('formidable');
// 创建网站服务器...引入http模块
...
// 处理formData路由请求
app.post('/formData', (res, req) => {
    // 创建formidable表单解析对象
    const form = new formidable.IncomingForm();
    // 解析客户端传过来的FormData对象 参数:错误对象 普通参数组成的对象 上传文件
    form.parse(req, (err, fields, files) => {
        res.send(fields);
    })
});

// 监听端口
app.listen(3000);
console.log("服务器响应成功");

4.3 实例方法

// 1.获取表单对象的属性的值
formData.get('key');

// 2.设置表单对象属性的值
formData.set('key', 'value');
// 注意:如果设置的key不存在,将会创建这个表单属性
// 注意:如果设置的key存在,将会改变这个表单属性的值

// 3.删除表单对象的属性
formData.delete('key');

// 4.向表单对象追加一个
formData.append('key', 'value');
var f = new FormData();//创建空的表单对象
f.append('sex','nan');
console.log(f.get('sex'));

4.4 FormData二进制文件上传

<input type="file" id="file">
<script>
    var file = document.getElementById('file');
    // 当用户选择文件的时候
    file.onchange = function(){
        var formData = new FormData();
        // 将用户选择的二进制文件追加到表单对象中
        formData.append('attrName', this.files[0]);
        // 创建ajax对象
        var xhr = new XMLHttpRequest();
        // 初始化ajax对象,请求方式必须为post
        xhr.open('post', 'http://localhost:3000/upload');
        xhr.send(formData);
        // 监听响应数据
        xhr.onload = function() {
            if(xhr.status == 200) {
                // 请求成功 响应正常
                console.log(xhr.responseText);
            }
        }

    }
</script>
// 服务器端
app.post('/upload', (req, res) => {
            // 创建解析对象
            const form = new formidable.IncomingForm();
            // 设置客户端上传文件的存储路径 __dirname找到当前目录,拼接后面的路径
            form.uploadDir = path.join(__dirname, 'public','uploads');
            // 保存文件后缀
            form.keepExtensions = true;
            // 解析客户端请求参数
            form.parse(req, (err, fields, files) => {
                res.send("ok");
            });
        })

文件上传进度展示

<div class = "progress">
    <div class = "progress-bar" id="bar" style="width:60%">60%</div>
</div>
var bar = document.getElementById('bar');
file.change = function() {
    // xhr的upload保存了文件上传的相关信息
    // 在文件上传过程 会持续触发onprogress事件(参数:事件对象)
    xhr.upload.onprogress = function(event) {
        // 文件上传了多少loaded
        // 文件总大小total
        var result = (event.loaded / event/total) * 100 + '%';
        // 将结果赋值给进度条的宽度属性
        bar.style.width = result;
        bar.innerHTML = result;
    }
}

上传图片即时预览

    form.parse(req, (err, fields, files) => {
        // attrName是客户端传过来的FormData对象的属性名
        res.send({
            path: files.attrName.path.split('public')[1]
        });
        // 此时得到的是/uploads/...jpg
    })
<div id="box"></div>
<script>
    var box = document.getElementById('box');
    xhr.onload = function() {
        if(xhr.status == 200) {
            var result = JSON.parse(xhr.responseText);
            // 动态创建img元素,不想让用户看到图片加载的过程
            var img = document.createElement('img');
            img.src = result.path;
            // 当图片加载完之后,显示到页面中
            // img上有onload事件 加载图片完触发
            img.onload = function() {
                box.appendChild(img);
            }
        }
    }
</script>

5. Ajax请求限制-同源政策

5.1 Ajax请求限制

什么是同源?

同源政策的目的

5.2 解决同源限制问题-使用JSONP

jsonp是json with padding的缩写,可以模拟ajax请求,但不是ajax请求

原理:利用script标签可以向非同源的服务器端发送请求的特性, 在服务端中返回函数调用的代码,(虽然服务端返回的是字符串,但因为写在客户端script中,会被当做js执行)当客户端加载完响应内容以后,这段响应内容会被当做js来执行,函数就被调用了,此时客户端已经提前准备好了函数的定义,通过函数的参数就可以获取接收的数据

(1)不同源的服务器端请求地址写在script标签的src属性中

<script src="www.example.com"></script>
<script src=“https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>

(2)服务端返回的是函数调用语句的字符串,(不是字符串就会直接在服务端执行,而实际我们想在客户端执行),同时发送给客户端的数据作为函数调用的参数传递

 const data = 'fn({name: "张三", age: "20"})';
 res.send(data);

(3)在客户端全局下定义好函数fn(以便返回的函数调用语句执行时不会说函数不存在)

 function fn (data) { }

(4)在 fn 函数内部对服务器端返回的数据进行处理

 function fn (data) { console.log(data); }

例子:

<!-- 1号网站http://localhost:3000 客户端 -->
  <script>
      function fn(data) {
          console.log('客户端的fn被调用了');
          console.log(data);
      }
  </script>
    <!-- 在下面服务器地址加载完毕后 会调用上面的函数 -->
  <script src="http://localhost:3001/test"></script>

// 2号网站http://localhost:3001 服务端
app.get('test', (req, res) => {
    const result = 'fn({name: "ccc"})';
    res.send(result);
})

JSON代码优化

<button id='btn'></button>
var btn = document.createElement('script');
script.src = 'http://localhost:3001/test';
document.body.appendChild(script);
// script标签加载完时触发
script.onload = function () {
    // 加载完 script标签就没有意义了
    document.body.removeChild(script);
}
script.src = 'http://localhost:3001/test?callback=fn';
// 2号网站http://localhost:3001 服务端
app.get('test', (req, res) => {
    const fnName = req.query.callback;
    // 将函数名称对应的函数调用代码返回客户端
    const result = fnName + '({name: "ccc"})';
    res.send(result);
    // 服务端以上代码优化 等价于下面一句
    // res.jsonp({name:"ccc"});
})
综合上面代码进行封装:
1.动态创建script标签,添加src属性为url

2.绑定加载事件onload,删除加载完无意义的当前script

完整的代码优化过程

5.3 CORS 跨域资源共享

CORS:全称为 Cross-origin resource sharing,即跨域资源共享,它允许浏览器向跨域服务器发送 Ajax 请求,克服了 Ajax 只能同源使用的限制

浏览器向服务端发送请求,请求头 (origin)

服务端向客户端返回响应,响应头(Access-Control-Access-Origin)

5.4 同源政策-服务端解决方案

服务端不存在同源政策

6. withCredentials属性

// 1.在网站1客户端中设置
// 当发送跨域请求时,携带cookie信息
xhr.wiithCredentials = true; 
xhr.send(formData);

withCredentials:指定在涉及到跨域请求时,是否携带cookie信息,默认值为false

Access-Control-Allow-Credentials:true 允许客户端发送请求时携带cookie

// 2.在网站2服务端中设置
// 允许客户端发送跨域请求时携带cookie信息
res.header('Access-Control-Allow-Credentials', true);
// 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
// 2.允许客户端使用哪些请求方法访问我
res.header('Access-Control-Allow-Methods', 'get,post')

7. $.ajax()

7.1 $.ajax()方法概述

7.1.1 作用:发送Ajax请求

 $.ajax({
     type: 'get',
     url: 'http://www.example.com',
     data: { name: 'zhangsan', age: '20' },
     contentType: 'application/x-www-form-urlencoded',
     beforeSend: function () { 
         return false
     },
     success: function (response) {},
     error: function (xhr) {}
});

 {
     data: 'name=zhangsan&age=20'
 }
 {
     contentType: 'application/json'
 }
JSON.stringify({name: 'zhangsan', age: '20'})

7.1.2 作用:发送jsonp请求

$.ajax({
    url: 'http://www.example.com',
    // 指定当前发送jsonp请求
    dataType: 'jsonp',
    // 修改callback参数名称,默认叫callback
    jsonp: 'cb',
    // 指定函数名称
    jsonCallback: 'fnName',
    success: function (response) {} 
})

7.2 serialize方法

作用:将表单中的数据自动拼接成字符串类型的参数

var params = $('#form').serialize();
// name=zhangsan&age=30

7.3 .get()、.post()

作用:.get方法用于发送get请求,.post方法用于发送post请求

$.get('http://www.example.com', {name: 'zhangsan', age: 30}, function (response) {}) 
$.post('http://www.example.com', {name: 'lisi', age: 22}, function (response) {})

三个参数:请求地址,请求参数,请求成功时回调函数(请求参数可省略)

8. jQuery中Ajax全局事件

8.1 全局事件

只要页面中有Ajax请求被发送,对应的全局事件就会被触发

全局事件必须被绑定在document元素上

.ajaxStart()     // 当请求开始发送时触发
.ajaxComplete()  // 当请求完成时触发
$(document).on('ajaxStart', function() {})

8.2 NProgress

官宣:纳米级进度条,使用逼真的涓流动画来告诉用户正在发生的事情!

<link rel='stylesheet' href='nprogress.css'/>
<script src='nprogress.js'></script>
NProgress.start();  // 进度条开始运动 
NProgress.done();   // 进度条结束运动
$(document).on('ajaxStart', function() {
    NProgress.start();
})

9. RESTful 风格的 API

9.1 传统请求地址

GET http://www.example.com/getUsers         // 获取用户列表
GET http://www.example.com/getUser?id=1     // 比如获取某一个用户的信息
POST http://www.example.com/modifyUser      // 修改用户信息
GET http://www.example.com/deleteUser?id=1  // 删除用户信息

9.2 RESTful API 概述

一套关于设计请求的规范

GET:      获取数据
POST:    添加数据
PUT:      更新数据
DELETE: 删除数据
请求数据 => 请求地址
users => /users
articles => /articles 

RESTful API 的实现:

GET:http://www.example.com/users 获取用户列表数据
POST:http://www.example.com/users 创建(添加)用户数据
GET:http://www.example.com/users/1 获取用户ID为1的用户信息
PUT:http://www.example.com/users/1 修改用户ID为1的用户信息
DELETE:http://www.example.com/users/1 删除用户ID为1的用户信息
// 服务器端
app.put('/users/:id', (req, res) => {
    const id = req.params.id;
    res.send(`当前我们在修改id为${id}的用户信息`);
})
//客户端
$.ajax({
    type: 'put',
    url: '/users/10',
    success: function(response) {
        console.log(response);
    }
})

10. XML

XML 的全称是 extensible markup language,代表可扩展标记语言,它的作用是传输和存储数据

 <students> 
     <student>
         <sid>001</sid>
         <name>张三</name>
         </student>
     <student>
         <sid>002</sid>
         <name>王二丫</name>
         </student>
 </students>

XML DOM

XML DOM 即 XML 文档对象模型,是 w3c 组织定义的一套操作 XML 文档对象的API。浏览器会将 XML 文档解析成文档对象模型

//客户端
xhr.onload = function () {
    // xhr.responseXML 获取服务器端返回的xml数据
    var xmlDocument = xhr.responseXML;
    var title = xmlDocument.getElementsByTagName('title')[0].innerHTML;
    container.innerHTML = title;
}
// 服务器端
app.get('/xml', (req, res) => {
    res.header('content-type', 'text/xml');
    res.send('<message><title>消息标题</title><content>消息内容</content></message>')
});
上一篇 下一篇

猜你喜欢

热点阅读