整理一些前后端交互的知识点

前后端交互

接口的调用方式
  • 原生的js — 手写原生的ajax的实现过程
  • 基于Jquery的ajax
  • fetch(ajax的升级版)
  • axios
// 安装服务
npm install http-server
// 设置启动端口
http-server -p 8000
URL地址格式
schema:// host:port/path?query#fragment
schema:协议 比如:http/https/ftp
host:域名或者ip地址
port:端口 http默认的端口是80 可以省略
path:路径   比如:/abc/a/b/c
query:查询的参数 比如:name=zhangsan&age=20
fragment:锚点(哈希地址hash) 用于定位页面的某个位置
// HTTP 请求方式 
GET  查询
POST  添加
PUT 修改
DELETE 删除
Promise的用法
传统ajax的调用数据接口
  • 异步调用
    • 异步效果
      • 定时任务
      • ajax
      • 事件函数
  • 多次异步调用的依赖
    • 多次异步调用的结果顺序是不确定的
    • 异步调用结果如果存在依赖需要,那就需要嵌套
// 逻辑代码
let ret = '----'
$.ajax({
    url: 'http://localhost:3000/data',
    success: function (data) {
        ret = data;
        console.log(ret);
    }
})

console.log(ret); // hello word

// 服务代码
app.get('/data', (req,res) => {
    res.send('hello word')
})
依赖分析

如果是同时调用不同的接口,打印的结果顺序是不确定

// 前端
$.ajax({
        url: 'http://localhost:3000/data',
        success: function (data) {
            console.log(data);
        }
    })

    $.ajax({
        url: 'http://localhost:3000/data1',
        success: function (data1) {
            console.log(data1);
        }
    })

    $.ajax({
        url: 'http://localhost:3000/data2',
        success: function (data2) {
            console.log(data2);
        }
    })

// 服务器
app.get('/data', (req, res) => {
    res.send('hello word')
})
app.get('/data1', (req, res) => {
    res.send('hello xiaomao')
})
app.get('/data2', (req, res) => {
    res.send('hello xiaoyang')
})

如何规定结果的顺序 – 必须使用回调函数

$.ajax({
    url: 'http://localhost:3000/data',
    success: function (data) {
        console.log(data);
        $.ajax({
            url: 'http://localhost:3000/data1',
            success: function (data1) {
                console.log(data1);
                $.ajax({
                    url: 'http://localhost:3000/data2',
                    success: function (data2) {
                        console.log(data2);
                    }
                })
            }
        })
    }
})
回调地狱

因为ajax的依赖关系导致一个非常深的函数的嵌套问题

function req1 () {
    $.ajax({
        url: 'http://localhost:3000/data',
        success: function (data) {
            console.log(data);
        }
    })
}

function req2 () {
    $.ajax({
        url: 'http://localhost:3000/data1',
        success: function (data1) {
            console.log(data1);
        }
    })
}

function req3 () {
    $.ajax({
        url: 'http://localhost:3000/data2',
        success: function (data2) {
            console.log(data);
        }
    })
}

Promise

Promise是用来实现异步处理的

优势:

  • 可以避免多层的嵌套
  • Promise提供了简洁API 让异步操作更简单

promise的使用

const promise = new Promise((resolve, reject) => {
    if (失败) {
        reject()
    }
    成功
    resolve()
    return promise
})
const p = new Promise(function (resolve, reject) {
    // 这个位置是实现具体的异步任务的
    setTimeout(function () {
        var flag = false
        if (flag) {
            // 正常情况
            resolve('hello')
        } else {
            reject('出错了')
        }

    }, 100)
})

调用.then

p.then(function(data){ }, function(error){ })
promise中使用ajax
function queryData (url) {
const 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('http://localhost:3000/data').then(function (data) {
        console.log(data);
        return queryData('http://localhost:3000/data1')
    }).then(function (data) {
        console.log(data);
        return queryData('http://localhost:3000/data2')
    }).then(function (data) {
        console.log(data);
    })

返回普通值

queryData('http://localhost:3000/data').then(function (data) {
    console.log(data);
    return new Promise(function(resolve, reject){
        setTimeout( () => {
            resolve('123')
        })
    })
}).then(function (data) {
    console.log(data);
    return 'hellohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh'
}).then(function (data) {
    console.log(data);
})
peomise中其他的API – catch

语法:

queryData('http://localhost:3000/data').then(function (data) {
    console.log(data);
}).catch(function(error) { console.log('发生错误', error) })
function queryData (url) {
    var p = new Promise(function (resolve, reject) {
        setTimeout(function () {
            reject('服务器错误')
        }, 100)
    })

    return p
}

queryData('http://locaohost:3000/data').then(function (data) {
    console.log(data);
}).catch(function (error) {
    console.log('发生错误:', error);
})
peomise中其他的API – finally

finally方法用于不管promise状态是如何的,都会执行

queryData('http://locaohost:3000/data').then(function (data) {
    console.log(data);
}).catch(function (error) {
    console.log('发生错误:', error);
}).finally(function(){
    console.log('finally');
})

peomise中其他的API – all

Promise.all() 方法用于将多个promise实列,包装成一个新的promise对象

const p = Promise.all([p1,p2,p3])

Promise.all接收一个数组作为参数, p1,p2,p3都是Promise的实列,如果不是,就会优先调用下面的还没讲的方法resolve(),将参数转为 promise实列

Promise.all() 方法的参数可以不是数组,但是必须是 iterator 接口类型的,返回的每个成员都是的 promise实列

p 的状态由 p1 , p2 , p3 决定,分成两种情况

1、只有 p1,p2,p3状态都变成 fulfilled , p的状态才是 fulfilled 这个时候p1,p2,p3、返回只组成一个数组,传递给 p 的回调函数

2、 只要p1,p2,p3之中有一个被 rejected p的状态就变成 rejected ,这个时候第一个被 rejected 实列的返回值,会传递 p 的回调函数

var p1 = queryData('http://localhost:3000/data')
var p2 = queryData('http://localhost:3000/data1')
var p3 = queryData('http://localhost:3000/data2')

console.log(p1, p2, p3);

var p =Promise.all([p1, p2, p3]).then(function (result) {
    console.log(result);
})

peomise中其他的API – race

race()同样是把多个 promise实列 包装成一个新的promise实列

const p = Promise.all([p1,p2,p3])

只要 p1,p2,p3 之中有一个实列先改变状态,p的状态就跟着改变,哪个先改变 promise实列的返回值,p接收的就是谁的返回值‘

fetch

是一种HTTP的请求方式,是XMLHttpRequest的一种替代方案,但是不是ajax的封装,是一种js属性,Fetch函数是原生的,没有使用XMLHttpRequest

fetch和ajax的差异
  • fetch()使用promise,不使用回调函数,简化了写法,更简洁
  • fetch使用的是模块化设计,API分散在多个对象上,输入、输出、状态都在同一个接口管理
  • fetch是通过数据流(stream对象)处理数据的,可以分块读取,有利于提高网站的性能
使用方式
fetch(url).then(fn)
		 .then(fn1)
		 .catch(fn3)
fetch('http://localhost:3000/fdata')
    .then(function(data){
        // data.text() 返回的是一个Promise对象 
        // text()属性FecthApi的一部分,用于获取后台的数据
        // console.log(data.text());
        return data.text()
    }).then(function(data){
        console.log(data); // undefined 
    })
async function getJson () {
    let url = 'http://localhost:3000/fdata';
    try {
        let response = await fetch(url)
        console.log(response);
        console.log(response.json());

    } catch (error) {
        console.log('Request Failed', error);
    }
}

getJson ()
Response对象: 处理HTTP请求
async function fetchText () {
    try{
        let response = await fetch('http://localhost:3000/fdata');
        console.log(response); // Response
    }catch (error) {
        console.log('Request Failed', error);
    }
}
fetchText()

Response包含的数据通过Stream接口异步获取,但是他还包含一些同步的属性,对用HTTP回应的标头信息(Headers) 可以立即读取

async function fetchText () {
    let response = await fetch('http://localhost:3000/fdata');
    console.log(response.status); // 200 
    console.log(response.statusText); // OK 
}
fetchText()
标头信息

Response.ok 返回一个布尔值

Response.status 属性返回的是一个数字 范围是 200 =< <=299

Response.statusText 属性返回的是一个字符串,表示HTTP回应的状态信息

Response.Type属性返回的请求类型 可能有下面的值

  • basic: 普通请求 就是同源请求
  • cors: 跨域请求
  • error: 网络错误,主要使用 service Worker
  • opaque: 如果fetch()请求的type属性设为 no-cors 就你会返回这个值,表示发出的是简单的跨域请求,类似表单的那种
  • opaqueredirect: 如果fetch请求的redirect属性为manual 就会返回这个值

Response.redirected :属性返回一个布尔值,表示请求是否发生跳转

async function fetchText () {
    let response = await fetch('http://localhost:3000/fdata');
    if (response.status >= 200 && response.status < 300) {
        return await response.text()
    } else {
        throw new Error(response.statusText)
    }
}
console.log(fetchText());

axios

使用npm安装

npm install axios 

使用 bower 安装

bower  install axios

使用纱

yarn  install axios

引入脚本

使用csdn

// 在线的网址

本地引入

    <script src="./js/axios.js"></script>

语法:

axios.get('/data').then(ret => { cosole.log(ret.data) })
axios.get('http://localhost:3000/adata')
    .then(function (ret) {
        // data属性是固定的 用户获取后台响应的数据
        // data是axios的API的一部分,用户获取后台数据
        console.log(ret);
    })
GET的使用方式

GET传递参数:

1、通过URL传递参数

2、通过params选项传递参数

通过URL传递参数
axios.get('/data?id=123').then(ret => { console.log(ret.data) })

第一种用法

// 数据请求
axios.get('http://localhost:3000/axios?id=123')
    .then(ret => {
        console.log(ret.data);
    })

// 服务器数据
app.get('/axios', (req, res) => {
    res.send('axios12345678' + req.query.id)
})

第二种用法

// 数据请求
axios.get('http://localhost:3000/axios/456')
    .then(ret => {
        console.log(ret.data);
})
// 服务器数据
app.get('/axios/:id', (req, res) => {
    res.send('axios12345678' + req.params.id)
})
通过params选项传递参数
axios.get(url, {
    params: {
        id:123
    }
}).then(function(ret){
    console.log(ret)
})
// 数据请求
axios.get("http://localhost:3000/axios", {
    params: {
        id: 7890
    }
}).then((ret) => {
    console.log(ret.data)
})

// 服务器
app.get('/axios', (req, res) => {
    res.send('axios12345678' + req.query.id)
})
delete的使用方式

通过url传递参数

axios.delete('/data?id=123').then(ret => {
    console.log(ret)
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值