• Vue2 基础四前后端交互


    代码下载

    前后端交互模式

    接口调用方式:原生ajax、基于jQuery的ajax、fetch、axios。

    URL 地址格式

    传统形式的 URL 格式:schema://host:port/path?query#fragment

    • schema:协议。例如http、https、ftp等
    • host:域名或者IP地址
    • port:端口, http默认端口80,可以省略
    • path:路径, 例如/abc/a/b/c
    • query :查询参数,例如 uname=lisi&age=12
    • fragment :锚点(哈希Hash),用于定位页面的某个位置

    Restful 形式的 URL HTTP请求方式:GET 查询、POST 添加、PUT 修改、DELETE 删除。

    Promise

    官网地址

    JavaScript的执行环境是单线程,常见的异步调用:定时任务、ajax、事件函数。多次异步调用的结果顺序不确定,异步调用结果如果存在依赖需要嵌套。

                        // 定时任务
                        let v = 1;
                        setTimeout(() => {
                            v = 2;
                        }, 1000);
                        console.log('v: ', v);
                        
                        // 多次异步调用
                        $.get('http:localhost/data1', function(data) {
                            console.log('data: ', data);
                        });
                        $.get('http:localhost/data2', function(data) {
                            console.log('data: ', data);
                        });
                        $.get('http:localhost/data3', function(data) {
                            console.log('data: ', data);
                        });
                        
                        // 嵌套调用
                        $.get('http:localhost/data1', function(data) {
                            console.log('data: ', data);
                            $.get('http:localhost/data2', function(data) {
                                console.log('data: ', data);
                                $.get('http:localhost/data3', function(data) {
                                    console.log('data: ', data);
                                });
                            });
                        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    Promise 是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。使用 Promise 主要有以下好处:

    • 可以避免多层异步调用嵌套问题(回调地狱)
    • Promise 对象提供了简洁的API,使得控制异步操作更加容易

    Promise 基本用法

    实例化 Promise 对象,构造函数中传递函数,该函数用于处理异步任务,resolve 和 reject 两个参数用于处理成功和失败两种情况,并通过 p.then 获取处理结果:

     var p = new Promise(function(resolve, reject){
        // 成功时调用 resolve()
        // 失败时调用 reject()
     });
     p.then(funciton(ret){
        // 从resolve得到正常结果
     }, function(ret){
        // 从reject得到错误信息
     });
     
     
    let p = new Promise(function(resolve, reject) {
        setTimeout(() => {
            let f = true;
            if (f) {
                resolve('正常');
            } else {
                reject('出错啦');
            }
        }, 1000);
    });
    p.then(function(data) {
        console.log('data: ', data);
    }, function(info) {
        console.log('info: ', info);
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    基于Promise处理Ajax请求

    处理原生Ajax:

                        let p = new Promise(function(resolve, reject) {
                            let xhr = new XMLHttpRequest();
                            xhr.open('GET', 'http:localhost/data1');
                            xhr.send();
                            xhr.onreadystatechange = function() {
                                if (xhr.readyState === 4) {
                                    if (xhr.status === 200) {
                                        resolve(xhr.responseText);
                                    } else {
                                        reject('出错啦');
                                    }
                                }
                            };
                        });
                        p.then(function(data) {
                            console.log('data: ', data);
                        }, function(info) {
                            console.log('info: ', info);
                        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    发送多次ajax请求:

                        function queryData(url) {
                            let p = new Promise(function(resolve, reject) {
                                let xhr = new XMLHttpRequest();
                                xhr.open('GET', url);
                                xhr.send();
                                xhr.onreadystatechange = function() {
                                    if (xhr.readyState === 4) {
                                        if (xhr.status === 200) {
                                            resolve(xhr.responseText);
                                        } else {
                                            reject('出错啦');
                                        }
                                    }
                                };
                            });
                            return p;
                        }
                        queryData('http:localhost/data1').then(function(data) {
                            console.log('data: ', data);
                            return queryData('http:localhost/data2');
                        }).then(function(data) {
                            console.log('data: ', data);
                            return queryData('http:localhost/data3');
                        }).then(function(data) {
                            console.log('data: ', data);
                        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    then参数中的函数返回值:

    • 返回 Promise 实例对象,返回的该实例对象会调用下一个 then
    • 返回普通值,返回的普通值会直接传递给下一个 then,通过 then 参数中的第一个函数的参数接收该值
                        function createPromise(flag) {
                            let q = new Promise(function(resolve, reject) {
                                setTimeout(() => {
                                    if (flag) {
                                        resolve('成功');
                                    } else {
                                        reject('失败');
                                    }
                                }, 1000);
                            });
                            return q;
                        }
                        createPromise(false).then(function(data) {
                            console.log('data: ', data);
                            return data;
                        }, function(info) {
                            console.log('info: ', info);
                            return info;
                        }).then(function(data) {
                            console.log('--data: ', data, '--');
                        }, function(info) {
                            console.log('--info: ', info, '--');
                        })
                        // 打印结果
                        // info:  失败
                        // --data:  失败 --
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    Promise常用的API

    • p.then() 得到异步任务的正确结果,也可以得到异步任务的正确结果和异常信息。
    • p.catch() 获取异常信息。
    • p.finally() 成功与否都会执行(尚且不是正式标准)。
    • Promise.all() 接受一个数组作参数,数组中的对象均为promise实例(如果不是一个 promise,该项会被用 Promise.resolve 转换为一个promise)。并发处理多个异步任务,所有任务都执行完成才能得到结果(全部任务成功才算成功,只要有一个任务异常就只能得到此任务的异常信息)。
    • Promise.race() 方法同样接受一个数组作参数。并发处理多个异步任务,只要有一个任务完成就能得到结果。
                        function queryData(flag, index) {
                            let p = new Promise(function(resolve, reject) {
                                setTimeout(() => {
                                    if (flag) {
                                        resolve('成功-' + index);
                                    } else {
                                        reject('失败-' + index);
                                    }
                                }, 1000);
                            });
                            return p;
                        }
                        queryData(true, 1).then(function(data){
                            console.log('then success data: ', data);
                        }).catch(function(info) {
                            console.log('catch info: ', info);
                        }).finally(function() {
                            console.log('finally');
                        });
                        // 打印结果:
                        // then success data:  成功-1
                        // finally
    
                        queryData(false, 2).then(function(data){
                            console.log('then success data: ', data);
                        }).catch(function(info) {
                            console.log('catch info: ', info);
                        }).finally(function() {
                            console.log('finally');
                        });
                        // 打印结果:
                        // catch info:  失败-2
                        // finally
    
                        Promise.all([queryData(true, 3), queryData(false, 4), queryData(false, 5)]).then(function(result) {
                            console.log('result: ', result);
                        }, function(info) {
                            console.log('error: ', info);
                        });
                        // 打印结果:
                        // error:  失败-4
    
                        Promise.race([queryData(true, 6), queryData(false, 7), queryData(true, 8)]).then(function(result) {
                            console.log('result: ', result);
                        }, function(info) {
                            console.log('error: ', info);
                        });
                        // 打印结果:
                        // result:  成功-6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    fetch

    官网地址

    • Fetch API是新的ajax解决方案,更加简单地获取数据,功能更强大、更灵活。
    • 语法结构 fetch(url, options).then(fn1).then(fn1).catch(fn2),Fetch会返回Promise,所以我们可以使用 then 拿到请求成功的结果。
    • fetch不是ajax的进一步封装,而是原生js,基于Promise实现,没有使用XMLHttpRequest对象。
                        fetch('http://localhost/data1').then(function(response) {
                            // response 是响应体
                            console.log('response: ', response);
                            // text()方法属于fetchAPI的一部分,它返回一个Promise实例对象,用于获取后台返回的数据
                            let r = response.text();
                            console.log('text: ', r);
                            return r;
                        }).then(function(data) {
                            // 这里得到的才是最终数据
                            console.log('data: ', data);
                        });
                        // 打印结果:
                        // response:  Response {type: 'cors', url: 'http://localhost/data1', redirected: false, status: 200, ok: true, …}
                        // text:  Promise {[[PromiseState]]: 'pending', [[PromiseResult]]: undefined}
                        // data:  data1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    fetch 请求参数,常用配置选项:

    • method(String): HTTP请求方法,默认为GET (GET、POST、PUT、DELETE)
    • body(String): HTTP的请求参数
    • headers(Object): HTTP的请求头,默认为{}

    fetch 响应数据格式:

    • text():将返回体处理成字符串类型
    • json():返回结果和 JSON.parse(responseText)一样
                        // get
                        fetch('http://localhost/fdata?id=1').then(function(res) {
                            return res.text();
                        }).then(function(data) {
                            console.log('data: ', data);
                        });
                        
                        // get 动态参数
                        fetch('http://localhost/fdata/2', {
                            method: 'get'
                        }).then(function(res) {
                            return res.text();
                        }).then(function(data) {
                            console.log('data: ', data);
                        });
                        
                        // post url-encoded 参数
                        fetch('http://localhost/fdata', {
                            method: 'post',
                            body: 'uname=张三&password=123456',
                            headers: {
                                'Content-Type': 'application/x-www-form-urlencoded'
                            }
                        }).then(function(res) {
                            return res.text();
                        }).then(function(data) {
                            console.log('data: ', data);
                        });
                        
                        // post josn 参数
                        fetch('http://localhost/fdata', {
                            method: 'post',
                            body: JSON.stringify({
                                uname: '李四',
                                password: '123456'
                            }),
                            headers: {
                                'Content-Type': 'application/json'
                            }
                        }).then(function(res) {
                            return res.json();
                        }).then(function(data) {
                            console.log('data: ', data);
                        });
                        
                        // delete
                        fetch('http://localhost/fdata/3', {
                            method: 'delete'
                        }).then(function(res) {
                            return res.text();
                        }).then(function(data) {
                            console.log('data: ', data);
                        });
                        
                        // put
                        fetch('http://localhost/fdata/4', {
                            method: 'put',
                            body: JSON.stringify({
                                uname: '王五',
                                password: '123456'
                            }),
                            headers: {
                                'Content-Type': 'application/json'
                            }
                        }).then(function(res) {
                            return res.json();
                        }).then(function(data) {
                            console.log('data: ', data);
                        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    axios

    axios(官网)是一个基于Promise 用于浏览器和 node.js 的 HTTP 客户端。它具有以下特征:

    • 支持浏览器和 node.js
    • 支持 promise
    • 能拦截请求和响应
    • 自动转换 JSON 数据

    基本用法:

    axios.get(‘/adata')
           .then(ret=>{
              // data属性名称是固定的,用于获取后台响应的数据
              console.log(ret.data)
           })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    axios 的响应结果的主要属性:

    • data : 实际响应回来的数据
    • headers :响应头信息
    • status :响应状态码
    • statusText :响应状态信息

    axios 的参数传递:

                        // get
                        axios.get('http://localhost/data?id=1')
                        .then(function(res) {
                            console.log(res.data);
                        });
    
                        // get 动态参数
                        axios.get('http://localhost/data/2')
                        .then(function(res) {
                            console.log(res.data);
                        });
    
                        // get params 形式参数
                        axios.get('http://localhost/data', {
                            params: {
                                id: 3
                            }
                        }).then(function(res) {
                            console.log(res.data);
                        });
    
                        // post 通过 URLSearchParams 传递url-encoded参数
                        let params = new URLSearchParams();
                        params.append('uname', '张三');
                        params.append('password', '123');
                        console.log(params);
                        axios.post('http://localhost/data', params).then(function(res) {
                            console.log(res.data);
                        });
    
                        // post json参数
                        axios.post('http://localhost/data', {
                            uname: '李四',
                            password: '123'
                        }).then(function(res) {
                            console.log(res.data);
                        });
    
                        // delete 与 get 类似
                        axios.delete('http://localhost/data?id=4')
                        .then(function(res) {
                            console.log(res.data);
                        });
                        axios.delete('http://localhost/data/5').then(function(res) {
                            console.log(res.data);
                        });
                        axios.delete('http://localhost/data', {
                            params: {
                                id: 6
                            }
                        }).then(function(res) {
                            console.log(res.data);
                        });
    
                        // put 与 post 类似
                        axios.put('http://localhost/data/7', {
                            uname: '王五',
                            password: '123'
                        }).then(function(res) {
                            console.log(res.data);
                        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    axios 还可以如此传递参数:

    axios({
        method: '请求类型',
        url: '请求的URL地址', 
        data: { /* POST数据 */ },
        params: { /* GET参数 */ }
    }).then(callback)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    axios 的全局配置:

    • axios.defaults.timeout = 3000; // 超时时间
    • axios.defaults.baseURL = ‘http://localhost:3000’; // 默认地址
    • axios.defaults.headers[‘mytoken’] = ‘aqwerwqwerqwer2ewrwe23eresdf23’; //设置请求头
    • axios.defaults.headers.common[‘Authorization’] = AUTH_TOKEN;
    • axios.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded’; // 配置公共的 post 的 Content-Type
                        axios.defaults.baseURL = 'http://localhost';
                        axios.defaults.headers['mytoken'] = 'zhaoliu';
                        axios.get('data-json')
                        .then(function(res) {
                            console.log(res.data);
                        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    axios 拦截器

    • 请求拦截器:请求拦截器的作用是在请求发送前进行一些操作,例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易
    • 响应拦截器:响应拦截器的作用是在接收到响应后进行一些操作,例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页
                        axios.interceptors.request.use(function(config) {
                            console.log('config: ', config);
                            console.log('url: ', config.url);
                            if (config.url.indexOf('/data-json1') !== -1) {
                                config.headers.mytoken = 'xxxx';
                            }
                            return config
                        });
                        axios.interceptors.response.use(function(res) {
                            console.log('response: ', res);
                            if (res.request.responseURL.indexOf('/data-json1') !== -1) {
                                return res.data;
                            }
                            return res;
                        }, function(err) {
                            console.log('err: ', err);
                        });
                        axios.get('http://localhost/data-json1')
                        .then(function(res) {
                            console.log('data: ', res);
                        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    接口调用-async/await用法

    async/await是ES7引入的新语法,它的实现是基于Promise,可以更加方便的进行异步操作:

    • async 关键字用于函数上(任何一个 async 函数都会隐式返回一个 promise)
    • await 关键字用于 async 函数当中,await函数不能单独使用(await可以得到异步的结果,也可以直接跟一个 Promise实例对象)
                        async function queryData() {
                            var ret = await axios.get('http://localhost/data/1')
                            return ret.data;
                        }
                        queryData().then(function(data) {
                            console.log('data: ', data);
                        });
                        
                        async function queryData() {
                            var ret = await new Promise(function(resolve, reject){
                                setTimeout(() => {
                                    resolve('100');
                                }, 1000);
                            });
                            return ret;
                        }
                        queryData().then(function(res) {
                            console.log('res: ', res);
                        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    async/await 让异步代码看起来、表现起来更像同步代码,多个异步请求的场景:

                        async function queryData() {
                            var info = await axios.get('http://localhost/data/1');
                            var ret = await axios.get('http://localhost/data?id=' + info.data.id);
                            return ret.data;
                        }
                        queryData().then(function(data) {
                            console.log('data: ', data);
                        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    综合案例——(基于后台接口的图书管理案例)

    axios 全局配置以及配置响应拦截器:

            // 全局配置 默认地址
            axios.defaults.baseURL = 'http://localhost:80/';
            // 响应拦截器
            axios.interceptors.response.use(function(res) {
                return res.data;
            });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    加载图书列表

    使用 async、await 封装 queryData 函数获取后台数据:

                    queryData: async function() {
                        this.books = await axios.get('books')
                    }
    
    • 1
    • 2
    • 3

    删除 mounted 钩子函数中的假数据,调用获取后台接口数据的函数 queryData:

                mounted: function() {
                    // 该生命周期钩子函数被触发的时候,模板已经可以使用
                    // 一般此时用于获取后台数据,然后把数据填充到模板
    
                    this.queryData();
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其他功能实现

    验证图书名是否可用:

                watch: {
                    bname: async function(n) {
                        if (n.length > 0) {
                            let ret = await axios.get('books/check/' + n);
                            console.log('ret: ', ret);
                            this.confirm = !ret.status;
                        } else {
                            this.confirm = false;
                        }
                    }
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    去编辑图书:

                    editHandle: async function(m) {
                        let ret = await axios.get('books/' + m.id);
                        if (ret !== null) {
                            this.bid = ret.id;
                            this.bname = ret.name;
                            this.flag = false;
                        }
                    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    添加、编辑图书:

                    addHandle: async function() {
                        console.log('addHandle');
                        if (this.flag) { // 添加
                            let ret = await axios.post('books', {
                                name: this.bname
                            })
                            // 成功重新加载数据
                            if (ret.code == 200) {
                                this.queryData();
                            }
                        } else { // 编辑
                            let ret = await axios.put('books', {
                                id: this.bid,
                                name: this.bname
                            });
                            // 成功重新加载数据
                            if (ret.code == 200) {
                                this.queryData();
                            }
                            this.flag = true;
                        }
                        this.bid = '';
                        this.bname = '';
                    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    删除图书:

                    deleteHandle: async function(m) {
                        let ret = await axios.delete('books/' + m.id);
                        // 成功重新加载数据
                        if (ret.code == 200) {
                            this.queryData();
                        }
                    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    图书管理后台实现

    新建后台项目文件夹 books, 安装 express、cros 这两个包。

    新建 handle.js 文件处理接口:

    // 处理文件
    const path = require('path');
    const fs = require('fs');
    const data = require('./data.json');
    
    // 生成图书id
    function generateBookId() {
        return Math.max.apply(null, data.map(function(v) {
            return v.id;
        })) + 1;
    }
    // 写入数据
    function writeData(res) {
        fs.writeFile(path.join(__dirname, 'data.json'), JSON.stringify(data), function(err) {
            if (err) {
                res.json({
                    code: 500,
                    err: err
                });
            } else {
                res.json({
                    code: 200,
                    msg: '成功'
                });
            }
        })
    }
    // 获取图书
    function books(req, res) {
        res.send(data);
    }
    // 添加图书
    function addBook(req, res) {
        const body = req.body;
        const book = {
            id: generateBookId(),
            name: body.name,
            date: + new Date()
        };
        console.log('book: ', book);
        data.unshift(book);
        writeData(res);
    }
    // 获取单个图书
    function oneBook(req, res) {
        console.log('params: ', req.params);
        const id = req.params.id;
        let book = null;
        data.some(function(v, i, a) {
            console.log('v: ', v);
            if (v.id == id) {
                book = v;
                return true;
            }
        });
        console.log('book: ', book);
        res.json(book);
    }
    // 编辑图书
    function editBook(req, res) {
        const body = req.body;
        console.log('body: ', body);
        data.some(function(v, i, a) {
            if (body.id == v.id) {
                v.name = body.name;
            }
        });
        writeData(res);
    }
    // 删除图书
    function deleteBook(req, res) {
        console.log('params: ', req.params);
        const id = req.params.id;
        data.some((v, i, a) => {
            if (v.id == id) {
                data.splice(i, 1);
            }
        });
        writeData(res);
    }
    // 验证图书名是否存在
    function checkName(req, res) {
        const name = req.params.name;
        let result = false;
        data.some(function(v, i, a) {
            result = name == v.name;
            return result;
        });
        res.json({
            status: result
        });
    }
    
    module.exports = {
        books,
        addBook,
        oneBook,
        editBook,
        deleteBook,
        checkName
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

    新建 router.js 文件,处理路由:

    // 路由模块
    let express = require('express');
    let router = express.Router();
    let handle = require('./handle');
    
    // 获取图书
    router.get('/books', handle.books);
    
    // 添加图书
    router.post('/books', handle.addBook);
    
    // 获取单个图书
    router.get('/books/:id', handle.oneBook);
    
    // 编辑图书
    router.put('/books', handle.editBook);
    
    // 删除图书
    router.delete('/books/:id', handle.deleteBook);
    
    // 验证图书名是否存在
    router.get('/books/check/:name', handle.checkName);
    
    module.exports = router;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    新建 index.js 文件,处理服务:

    // 导入 express
    const express = require('express');
    
    // 创建服务器
    const app = express();
    
    // 配置 cors 跨域中间件
    const cors = require('cors');
    app.use(cors());
    // 配置解析 application/x-www-form-urlencoded 格式的表单数据的中间件
    app.use(express.urlencoded({ extended: false }));
    // 配置解析表单中的 JSON 格式的数据的中间件
    app.use(express.json());
    
    // 启动静态资源服务
    app.use(express.static('public'))
    
    // 配置路由
    let router = require('./router');
    app.use(router);
    
    // 指定端口,启动服务器
    app.listen(80, function(){
        console.log('server running at http://127.0.0.1:80');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    附录

    附录一

    示例 node 后台代码:

    // 导入模块
    const express = require('express');
    // 创建服务器
    const app = express();
    
    // 配置跨域中间件
    app.use(function(req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
        res.header('Access-Control-Allow-Headers', 'Content-Type');
        next();
    });
    // 配置自定义请求头
    app.use('/data-json', function(req, res, next) {
        res.header('Access-Control-Allow-Headers', 'mytoken');
        next();
    });
    app.use('/data-json1', function(req, res, next) {
        res.header('Access-Control-Allow-Headers', 'mytoken');
        next();
    });
    
    // 配置数据解析中间件
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    
    // 监听请求
    app.get('/data1', function(req, res) {
        console.log('----data1----');
        res.send('data1');
    });
    app.get('/data2', function(req, res) {
        console.log('----data2----');
        res.send('data2');
    });
    app.get('/data3', function(req, res) {
        console.log('----data3----');
        res.send('data3');
    });
    
    app.get('/data', function(req, res) {
        console.log(req.query);
        res.send({
            method: 'get',
            ...req.query
        });
    });
    app.get('/data/:id', function(req, res) {
        console.log(req.params);
        res.send({
            method: 'get',
            ...req.params
        });
    });
    app.post('/data', function(req, res) {
        console.log(req.body);
        res.send({
            method: 'post',
            ...req.body
        });
    });
    app.delete('/data', function(req, res) {
        console.log(req.params);
        res.send({
            method: 'delete',
            ...req.query
        });
    });
    app.delete('/data/:id', function(req, res) {
        console.log(req.params);
        res.send({
            method: 'delete',
            ...req.params
        });
    });
    app.put('/data/:id', function(req, res) {
        console.log(req.params);
        console.log(req.body);
        res.send({
            method: 'put',
            id: req.params.id,
            ...req.body
        });
    });
    
    app.get('/data-json', (req, res) => {
        console.log(req.headers);
        res.json({
            uname: '赵六',
            age: 12
        });
    });
    app.get('/data-json1', (req, res) => {
        console.log(req.headers);
        res.json({
            uname: '赵六',
            age: 12
        });
    });
    
    // 调用 app.listen(端口号, 启动成功后的回调函数),启动服务器
    app.listen(80, function() {
        console.log('server running at http://127.0.0.1:80');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
  • 相关阅读:
    Python的安装
    vs工程添加自定义宏
    数据库理论 06 存储管理和索引——基于《数据库系统概念》第七版
    C专家编程 第10章 再论指针 10.8 轻松一下---程序检验的限制
    赶紧进来看看---详细介绍五种常用字符串库函数 以及对库函数的模拟实现
    《低代码指南》——低代码+AI,驱动企业数字资产保值增值
    uniapp的组件封装与组件间的参数传递
    Vue3中组合式API(简单用法)
    CSS的美化(文字、背景) Day02
    利用Abp过滤器实现业务数据“回收站”功能
  • 原文地址:https://blog.csdn.net/jiuchabaikaishui/article/details/137912992