前后端交互

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)
        })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容