前后端交互

1 前后端交互模式

1.1接口调用方式:
  • 原生AJAX
  • 基于JQuery的AJAX
  • fetch
  • axios

原生的ajax比较的麻烦,而jquery主要是简化dom操作的js库,我们在vue中一般是用不到jquery的,所以重点学习后面两种方法

1.2 url地址形式

schema:协议
host:服务器IP地址
post:端口号,80端口可以省略
path:路径,如manager/login/index
param:参数
fragment:锚点,用于定位页面的某个位置

  • RESTful形式的url地址

2 Promise用法

2.1异步调用

常见的异步情况:
1 定时任务
2 ajax
3 事件函数

2.2 Promise基础
var p = new Promise(function(resolve,reject){
            //成功时调用resolve
            //失败时调用reject
        })
        p.then(function(ret){
            //从resolve中得到正常结果
        })
        .catch(function(ret){
            //从reject中得到失败结果
        })

Promise是用于解决回调地狱的问题

基于Promise处理Ajax
function queryData(url){
            var p = new Promise(function(resolve,reject){
                var xhr = new XMLHttpRequest()
                xhr.onreadystatechange = function(){
                    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
        }
发送一次请求:
        queryData('http://localhost:3000/data')
        .then(function(data){
            console.log(data);
        },function(info){
            console.log(info)
        })
发送多个请求并保证顺序:

queryData(url).then(function(data){
            console.log(data);
            return queryData(url2)
        }).then(function(data){
            console.log(data);//打印的是url2返回来的数据
            return queryData(url3)
        }).then(function(data){
            console.log(data);//打印的是url3返回来的数据
            
        })

由此,解决了回调地狱的问题

then参数中的函数返回值

1 如果返回的是一个promise实例对象,该实例对象会调用下一个then
2 如果返回的是一个普通值,返回的普通值会直接传递给下一个then,通过then参数中的函数参数接收该值。其实如果return的是一个普通的值,会默认生成一个promise实例对象来调用下一个then

Promise常用的API

对一个对象用console.dir()打印,在prototype中的方法就是实例方法,直接打印出的方法就是对象方法

实例方法:(在Promise实例中可以调用的方法)
p.then()//得到异步任务的正确结果
p.catch()//得到异步任务的异常结果
p.finally()//成功与否都会执行 (尚且不是正式标准)

对象方法:(直接可以在Promise名称后面调用的方法)
Promise.all()//并发处理多个异步任务,所有任务都执行完成才能得到结果
Promise.race()//并发处理多个异步任务,只要又一个任务完成就能得到结果

fetch API

3.1 fetch 概述
1 语法特性

1 xhr的升级版
2 基于Promise实现

2 语法结构

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

fetch('http://localhost:3000/getData')
            .then(function(data){
                //text方法属于fetchAPI的一部分,返回的不是数据,而是一个Promise对象
                return data.text()
            }).then(function(data){
                console.log(data);
            })
//经测试,使用fetch,没有为前端页面开服务,照样拿到了后台数据,ajax则不行
3.2 fetch请求参数
1 常用配置选项:
  • methods(String):HTTP请求方法,默认为GET(GET、POST、PUT、DELETE)
  • body(String):HTTP的请求参数
  • headers(Object):HTTP的请求头,默认为{}
2 GET请求方式的参数传递
//传统url传参数
        fetch('http://localhost:3000/params?id=123').then(data=>{
            return data.text()
        }).then(ret=>{
            console.log(ret)
        })
服务器端:
app.get('/params',function(req,res){
    // console.log(r);
    if(req.query.id=='123'){
        res.send('传统的url传参数')
    }
    else{
        res.send('oh-no')
    }
})

//RESTful 风格的传参数
        fetch('http://localhost:3000/params/123',{
            method:'get'
        }).then(data=>{
            return data.text()
        }).then(ret=>{
            console.log(ret)
        })
服务器端:
app.get('/params/:id',function(req,res){
    // console.log(r);
    if(req.params.id=='123'){
        res.send('RESTful形式的url')
    }
    else{
        res.send('oh-no')
    }
})
DELETE 和GET基本是一致的
POST请求参数传递
// 传递传统参数
fetch('http://localhost:3000/params',{
            method:'post',
            body:'uname=lisi&pwd=123',
            headers:{
                'Content-Type':'application/x-www-form-urlencoded'
            }
        }).then(data=>{
            return data.text()
        }).then(ret=>{
            console.log(ret)
        })

//传递JSON格式的数据
fetch('http://localhost:3000/params',{
            method:'post',
            body:JSON.stringify({
                uname:'lisi',
                pwd:'123456'
            }),
            headers:{
                'Content-Type':'application/json'
            }
        }).then(data=>{
            return data.text()
        }).then(ret=>{
            console.log(ret)
        })
PUT

put和post类似

前端
fetch('http://localhost:3000/putTest/123',{
            method:'put',
            body:JSON.stringify({
                uname:'lisi',
                pwd:'123456'
            }),
            headers:{
                'Content-Type':'application/json'
            }
        }).then(data=>{
            return data.text()
        }).then(ret=>{
            console.log(ret)
        })
后端:
app.put('/putTest/:id',function(req,res){
    res.send('fetch的put传参'+ req.params.id +req.body.uname +'----' +req.body.pwd)
})
fetch响应结果
  • text():将返回体处理成字符串格式
  • json():返回结果和JSON.parse(responseText)一样

接口调用axios

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

  • 支持浏览器和node
  • 支持Promise
  • 能够拦截请求和响应
  • 自动转换JSON数据
基本用法:
axios.get('http://localhost:3000/json')
            .then(ret=>{
                console.log(ret.data);
            })
常用的API
  • get
  • post
  • put
  • delete
get传递参数

1 直接通过url传参数
2 通过params传递参数

axios.get('http://localhost:3000/axiosTest?id=111')
            .then(ret=>{
                console.log(ret.data);
            })
        axios.get('http://localhost:3000/axiosTest/123')
            .then(ret=>{
                console.log(ret.data);
            })
        axios.get('http://localhost:3000/axiosTest',{
            params:{
                id:'hahahha'
            }
        })
            .then(ret=>{
                console.log(ret.data);
            })

以上三种传参方法都可以使用,同时delete参数传递和get是类似的。
注:前端用params传参的话,后端用的是query来接收数据,而不是params

POST请求传参
axios.post('http:///localhost:3000/axiosPost',{//默认传递的是json格式的数据
            id:'fsafsf',
            pwd:'12321',
            uname:'zhazhafei'
        }).then(function(ret){
            console.log(ret.data)
        })
        //post传递表单格式的数据
        const params = new URLSearchParams()
        params.append('id','hahha')
        params.append('pwd','123')
        params.append('uname','zhangsan')
        axios.post('http://localhost:3000/axiosPost',params).then(
            function(ret){console.log(ret.data);
            }
        )

服务端:
app.post('/axiosPost',function(req,res){
    res.send('post传参数--用户名:'+ req.body.uname)
})

put和post类似

axios响应信息
  • data:实际响应回来的数据
  • headers:实际响应头信息
  • status:响应状态码
  • statusText:响应状态信息
axios的全局配置
axios.defaults.timeout = 3000
        //配置请求头信息
        axios.defaults.headers['mytoken'] = 'hello'//添加了一个名为hello的header
        //配置URL基路径
        axios.defaults.baseURL  =  'http://localhost:3000' //请求的基准url地址
axios拦截器
请求拦截器
image.png

eg:

这样的话,这个请求就增加了一个请求头交mytoken
axios.interceptors.request.use(function(config){
            console.log(config.url)
            config.headers.mytoken = 'hello' //配置请求头 
            return config
        },function(err){
            console.log(err)
        })
        axios.get('http://localhost:3000/getJson').then(function(ret){
            console.log(ret)
        })
image.png
响应拦截器
image.png
//配置响应拦截器
        axios.interceptors.response.use(function(res){
            //这里的ret是axios包装的那个对象
            //ret.data就是具体的数据
            return res
        },function(err){
            console.log(err)
        })

比如,我们想要让axios里的数据不是那个对象,而是具体的data,我们可以在响应拦截器里这样写:

/配置响应拦截器
        axios.interceptors.response.use(function(res){
            //这里的ret是axios包装的那个对象
            //ret.data就是具体的数据
            return res.data
        },function(err){
            console.log(err)
        })
        axios.get('http://localhost:3000/getJson').then(function(ret){
            console.log(ret)
        })

接口调用的async/await用法

1 基本用法

async/await是ES7引入的语法,为的是更加方便的进行异步操作
async用在函数上
await用于函数的内部

eg:

       async function queryData(url){
            const ret = await axios.get(url)
            return ret //返回值是一个Promise实例对象
        }
        queryData('http://localhost:3000/json').then(function(data){
            console.log(data.data)
        })

注:await后面应该跟一个Promise的实例对象。async函数的返回值是一个Promise实例对象

async/await处理多个异步请求

例子:

axios.defaults.baseURL = 'http://localhost:3000'
        async function queryData(){
            var info = await axios.get('/async')//把第一次的结果第二次的参数
            var ret = await axios.get('/async2?info='+info.data)//那么就要求第二次必须比第一次后执行
            return ret
        }
        queryData().then(function(ret){//执行的结果是一个Promise实例,所以可以用then
            console.log(ret.data)
        })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容