• 三、vue前后端交互(轻松入门vue)


    轻松入门vue系列

    六、Vue前后端交互

    项目中一般结合async/await语法使用axios调用接口

    1. 前后端交互模式

    1. 接口调用方式

    原生ajax、基于jQuery的ajax、fetch、axios

    2. 传统的URL

    格式:schema://host:port/path?query#fragment

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

    3. Restful形式的URL

    HTTP请求方式

    1. GET 查询
    2. POST 添加
    3. PUT 修改
    4. DELETE 删除

    2. Promise的相关概念和用法

    JS中常见的异步调用:定时任务、ajax、事件函数

    Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。

    使用Promise主要有以下好处:

    • 可以避免多层异步调用嵌套问题(回调地狱)
    • Promise对象提供了简介的API,使得控制异步操作更加容易
    Promise基本用法
    • 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务。

    • resolve和reject两个(方法)参数用于处理成功和失败两种情况,并通过p.then获取处理结果。

    var p = new Promise(function(resolve,reject){
    	//成功时调用resolve()
    	//失败时调用reject()
    });
    p.then(function(ret){
    	//从resolve得到正常结果
    },function(ret){
    	//从reject得到错误信息
    });
    
    then参数中的函数返回值
    1. 返回Promise实例对象

    返回该实例对象用于调用下一个then

    p.then(function(ret){
    	return new Promise(...)
    }).then(...)
    
    1. 返回普通值

    返回的普通值会直接传递给下一个then,通过then函数中函数的参数接收该值(底层会对返回的普通值封装为一个Promise使得能够继续调用then)

    p.then(function(ret){
    	return '莫逸风';	
    }).then(function(ret){
    	alert(ret);		//莫逸风
    })
    
    基于Promise处理多个Ajax请求demo
    <script>
        //Promise基本使用,原生ajax
        function getText(url) {
            var p = new Promise(function (resolve, reject) {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    //readyState表示文档状态
                    if (xhr.readyState != 4) return;
                    if (xhr.readyState == 4 && xhr.status == 200){
                        //处理正常情况
                        resolve(xhr.responseText);
                    }else {
                        reject('服务器错误');
                    }
                };
                xhr.open('get',url);
                xhr.send(null);
            });
            return p;
        }
        //链式调用解决回调地狱,return一个新的调用就可以继续调用新的then()了。
        getText('http://localhost:8088/saymo').then(
            function (data) {
                alert(data);
                return  getText('http://localhost:8088/sayyi');
            },function (info) {
                alert(info);
            }
        ).then(
            function (data) {
                alert(data);
                return getText('http://localhost:8088/sayfeng')
            }
        ).then(
            function (data) {
                alert(data);
            }
        );
    </script>
    

    上方调用方式会调用后端,产生跨域问题(解决方案回头仔细研究,先放一段代码(SpringBoot))

    跨域解决方案参考

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    
    @Configuration
    public class CorsConfig {
        public CorsConfig(){
        }
    
        @Bean
        public CorsFilter corsFilter(){
            //1.添加cors配置信息
            CorsConfiguration config = new CorsConfiguration();
            config.addAllowedOrigin("http://localhost:63343");
            //设置是否发送cookie信息
            config.setAllowCredentials(true);
            //设置允许请求的方式
            config.addAllowedMethod("*");
            //设置允许的header
            config.addAllowedHeader("*");
    
            //2.为url添加映射路径
            UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
            corsSource.registerCorsConfiguration("/**",config);
    
            //3.返回从新定义好的corsSource
            return new CorsFilter(corsSource);
        }
    }
    
    
    Promise常用API
    1. 实例方法

    p.then() //得到异步任务的处理结果
    p.catch() //获取异常信息
    p.finally() //成功与否都会执行(尚且不是正式标准)

    demo

    <script>
        function foo() {
            return new Promise(function (resolve, reject) {
                setTimeout(function () {
                    //resolve(123)//正常情况
                    reject("出错了");//错误情况
                },1000)
            })
        }
        foo().then(function (data) {
            alert(data);
        }).catch(function (data) {
            alert(data);
        }).finally(function () {
            alert("结束了")
        })
        //与上面效果相同
        foo().then(function (data) {
            alert(data);
        },function (data) {
            alert(data);
        }).finally(function () {
            alert("结束了")
        })
    </script>
    
    1. 对象方法

    Promise.all()并发处理多个异步任务,所有任务都执行完成才能得到结果

    Promise.race()并发处理多个异步任务,只要有一个任务完成就能得到结果

    demo

    <script>
        function getText(url) {
            var p = new Promise(function (resolve, reject) {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    //readyState表示文档状态
                    if (xhr.readyState != 4) return;
                    if (xhr.readyState == 4 && xhr.status == 200){
                        //处理正常情况
                        resolve(xhr.responseText);
                    }else {
                        reject('服务器错误');
                    }
                };
                xhr.open('get',url);
                xhr.send(null);
            });
            return p;
        }
    
        var p1 = getText("http://localhost:8088/saymo");
        var p2 = getText("http://localhost:8088/sayyi");
        var p3 = getText("http://localhost:8088/sayfeng");
    
        //result是一个数组形式的三个数据,顺序和p1,p2,p3顺序相同
        Promise.all([p1,p2,p3]).then(function (result) {
            alert(result);
        })
        //result返回一个数据,最快返回的一个
        Promise.race([p1,p2,p3]).then(function (result) {
            alert(result);
        })
    </script>
    

    3. fetch进行接口调用

    更加简单的数据获取方式,功能更强大、更灵活,可以看做是xhr的升级版

    基于Promise实现

    fetch基本用法

    语法结构

    fetch(url).then(fn2)
    		  .then(fn3)
    		  ...
    		  .cach(fn)
    

    基本用法

    fetch('/abc').then(data=>{
    	return data.text();
    }).then(ret=>{
    	//这里得到的才是最终的数据
    	console.log(ret);
    })
    

    demo

    <script type="application/javascript">
        /**
         * Fetch API 基本用法
         */
        fetch('http://localhost:8088/saymo').then(function (data) {
            //text()方法属于fetchAPI的一部分,它返回一份Promise实例对象,用于获取后台返回的数据
            return data.text();
        }).then(function (data) {
            alert(data);
        })
    </script>
    
    fetch请求参数
    1. 常用配置选项

    method(String):HTTP请求方法,默认为GET(GET、POST、PUT、DELETE)

    body(String):HTTP的请求参数

    headers(Object):HTTP的请求头,默认为{}

    1. get请求方式的参数传递

    常规

    <script>
        fetch('http://localhost:8088/sayHi?name="莫逸风',{
            method:'get'
        }).then(function (data) {
            return data.text();
        }).then(function (data) {
            alert(data);
        });
    </script>
    

    restful形式

    
    
    1. post请求方式的参数传递

    参数form表单形式

    fetch('http://localhost:8088/login',{
            method:'post',
            body:,
            headers:{
                'Content-Type':'application/x-www-form-urlencoded',
            }
        }).then(function (data) {
            return data.text();
        }).then(function (data) {
            alert(data);
        })
    

    参数json表单形式

    fetch('http://localhost:8088/login',{
            method:'post',
            body:JSON.stringify({
                name:'莫逸风',
                pass:'1234',
            }),
            headers:{
                'Content-Type':'application/json',
            }
        }).then(function (data) {
            return data.text();
        }).then(function (data) {
            alert(data);
        });
    
    fetch响应结果

    text():将返回体处理成字符串类型

    json():返回结果和JSON.parse(responseText)一样

    fetch('http://localhost:8088/sayhi?name=莫逸风',{
            method:'get'
        }).then(function (data) {
            return data.json();
        }).then(function (data) {
            alert(data);
        });
    

    4. axios进行接口调用

    axios(官网:https://github.com/axios/axios)是一个基于Promise用于浏览器和node.js的HTTP客户端

    中文说明文档

    它具有一下特征:

    • 支持浏览器和node.js
    • 支持promise
    • 能拦截请求和相应
    • 自动转换JSON数据
    axios基本用法
    //去github下载文件,此js位于axios-masterdist
    <script src="axios.js"></script>
    <script>
        axios.get('http://localhost:8088/saymo').then(function (ret) {
            //data属性是固定的用法,用于获取后台的实际数据
            alert(ret.data)
        })
    </script>
    
    axios的常用API(参数传递)
    • get:查询数据
    • post:添加数据
    • put:修改数据
    • delete:删除数据
    1. get传递参数

    通过URL传递参数

    axios.get('http://localhost:8088/sayhi?name=莫逸风').then(function (ret) {
            alert(ret.data)
        })
    

    restful风格接口

    
    

    通过params选项传递参数

    axios.get('http://localhost:8088/sayhi',{
            params:{
                name:"莫逸风"
            }
        }).then(function (ret) {
            //data属性是固定的用法,用于获取后台的实际数据
            alert(ret.data)
        })
    
    1. POST传递参数

    通过对象传递参数(默认传递的是json格式的数据)

    axios.post('http://localhost:8088/login',{
            name:"莫逸风",
            pass:"1234",
        }).then(function (ret) {
            //data属性是固定的用法,用于获取后台的实际数据
            alert(ret.data)
        })
    

    通过URLSearchParams传递参数(application/x-www-form-urlencoded)

    var param = new URLSearchParams();
    param.append('name','莫逸风');
    param.append('pass','12345');
        axios.post('http://localhost:8088/login',param).then(function (ret) {
            //data属性是固定的用法,用于获取后台的实际数据
            alert(ret.data)
        })
    
    1. axios的响应结果
    • data:实际响应回来的数据
    • headers:响应头信息
    • status:响应状态码
    • statusText:响应状态信息
    axios.post('http://localhost:8088/login',param).then(function(ret){
    	console.log(ret);//所有数据都包含在此对象中
    	//对于json形式的响应数据可以直接获取,不需要转换
    	alert(ret.data.name);
    })
    
    1. axios的全局配置
    axios.defaults.timeout = 3000;  //超时时间
    //默认地址,再写请求的时候只需要写后面的路由就行了
    axios.defaults.baseURL = 'http://localhost:3000/app';
    axios.defaults.headers['mytoken']='aqwerwqwerqwer2ewrwe23eresdff23'//设置请求头
    

    demo

    //配置请求的基准URL地址
    axios.defaults.baseURL = 'http://localhost:8088/';
    axios.get('sayhi?name=莫逸风').then(function (ret) {
        //data属性是固定的用法,用于获取后台的实际数据
        alert(ret.data)
    })
    
    //注意,添加请求头跨域需要后端设置AllowedHeader
    //修改请求头
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    
    1. axios拦截器

    请求拦截器

    在请求发出之前设置一些信息

    axios.interceptors.request.use(function (config) {
            config.baseURL = "http://localhost:8088/";
            alert(config.url);
            return config;
        },function (err) {
            console.log(err);
        })
    
        axios.get('sayhi?name=莫逸风').then(function (ret) {
            //data属性是固定的用法,用于获取后台的实际数据
            alert(ret.data)
        })
    

    响应拦截器(拦截器放到请求之上)

    在获取数据之前对数据做一些加工处理

    axios.interceptors.response.use(function (res) {
            var data = res.data;
            return data;
        },function (err) {
            console.log(err);
        })
    
        axios.get('sayhi?name=莫逸风').then(function (res) {
            //data属性是固定的用法,用于获取后台的实际数据
            alert(res)
        })
    

    5. asyns/await接口调用

    async/await的基本用法
    • async/await是ES7引入的语法,可以更加方便的进行异步操作

    • async关键字用于函数上(async函数的返回值是Promise实例对象)

    • await关键字用于async函数中(await可以得到异步的结果)

    await后跟一个Promise对象实现异步任务,async返回值是一个Promise对象

    <script src="axios.js"></script>
    <script>
        axios.defaults.baseURL = 'http://localhost:8088/';
        async function queryData(){
            var ret = await axios.get('saymo');
            //alert(ret.data);
            return ret.data;
        }
        queryData().then(function (data) {
            alert(data);
        });
    </script>
    
    多个异步请求的场景

    不需要.then来保证顺序。

    <script>
        axios.defaults.baseURL = 'http://localhost:8088/';
        async function queryData(){
            var ret = await axios.get('saymo');
            alert(ret.data);
            var ret1 = await axios.get('sayyi');
            alert(ret1.data);
            var ret2 = await axios.get('sayfeng');
            return ret2.data;
        }
        queryData().then(function (data) {
            alert(data);
        });
    </script>
    
  • 相关阅读:
    cocos2dx 将cocosbuilder输出文件映射成对象的原理
    网络游戏剧情副本的一种实现方式(上)
    2D游戏中的碰撞检测
    es学习笔记2:php版本es包
    go语法:参数传递
    go语法专题:信号量,iota,锁原理
    https协议原理与实现(整理中)
    我眼中的幸福
    戏剧的一天
    开通了
  • 原文地址:https://www.cnblogs.com/zhangguangxiang/p/14232516.html
Copyright © 2020-2023  润新知