前端与移动开发----Ajax编程----跨域,axios,异步编程,协议加强

Ajax编程

回顾

  1. JS数据 -> JSON字符串

    • JSON.stringify()
  2. JSON字符串 -> JS数据

    • JSON.parse()
  3. JSON文件里必须用双引号, 格式要求严谨

  4. XHR2新增功能

    • timeout - 超时时间设置
    • ontimeout - 超时的事件 (而且自动停止这次请求)
  5. 使用onload替代onreadystatechange

  6. 前台往后台传递数据的方式

    • GET方式: 通过url后面?key=value&key=value格式字符串
    • POST方式
      • body体里: key=value&key=value 格式的字符串
      • body体里: 表单二进制流 前端用FormData() 来装载

    什么方式, 什么内容类型, 参数名, 都要和后台对上

  7. 上传文件

    • 通过FormData装载然后传递给后台的api接口

11. 跨域介绍

11.0 什么是跨域?

Ajax所在页面的协议,域名和端口, 与要请求的URL的协议, 域名, 端口有一个不一致的就产生跨域

  • 跨域报错提示: (记住开头3个单词)

在这里插入图片描述

// Ajax所在html页面的 协议/域名/端口号 和
// Ajax要请求的url的  协议/域名/端口号  对不上就发生跨域访问

// 例如:
// 当前Ajax所在html页面(假设用live server插件打开) - http://127.0.0.1:5500
// Ajax要请求的url地址                            - http://网页新闻/
// 这就发生了跨域
$.ajax({
    
    
    url: "http://c.m.163.com/nc/article/headline/T1348647853363/0-40.html",
    type: "GET",
    success (res) {
    
    
        console.log(res);
    }
})

// 总结: 运行后报错
// Access to XMLHttpRequest at 'http://c.m.163.com/nc/article/headline/T1348647853363/0-40.html' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
// Access to XMLHttpRequest  - 连接访问XMLHttpRequest
// at xxx from origin yyy    - 从yyy地址到xxx地址
// has been blocked by CORS policy: - 已被CORS策略阻止
// No 'Access-Control-Allow-Origin' header is present on the requested resource - 请求的资源上不存在“Access Control Allow Origin”标头

同源策略

  • 同源:

    • Ajax所在页面的协议,域名和端口, 与要请求的URL的协议, 域名, 端口全都一样就是同源
  • 跨域:不同源就是跨域

    • Ajax所在页面的协议,域名和端口, 与要请求的URL的协议, 域名, 端口有一个不一致的就产生跨域

它是浏览器提供的一种安全机制,限制来自不同源的数据。现代浏览器会先判断服务器是否允许跨域, 如果不允许则报错 (后端不支持跨域请求)

11.1 跨域解决方案 - jsonp

我们希望:浏览器可以通过Ajax跨域得到数据

  • jsonp (需要前端和后端的配合才可以)- 不常用

    • 除了Ajax能发送请求, script标签也能请求一个URL地址来拿到东西吧?
<!-- 1. (必须理解): script的src引入的文件, 其实就是把文件里所有的内容, 都下载引入进来, 放到script里当做js代码执行了 -->
<!-- <script src="./11.1.txt"></script> -->


<!-- 2. 那我这个地址里返回一串JS函数调用的代码呢? -->
<!-- src引入的代码是 callbackFn(数组) - 是不是在调用这个页面callbackFn函数执行呢? -->
<script>
    function callbackFn(arr) {
     
     
        // 函数被下面src引入地址的代码执行了
        console.log(arr);
    }
</script>
<script src="./11.2"></script>



<!-- 3. jsonp使用 -->
<!-- jsonp只是个概念, 和JSON没关系, 这里请求后台的接口, 后台接口会返回你传给后台的方法名(后台的数据) 回来, 嵌入到script执行, 调用你定义好的myFn执行并且把值传入 -->
<script>
    function myFn(arr) {
     
     
        console.log(arr);
    }
</script>
<script src="http://123.57.109.30:3006/api/jsonp?callback=myFn"></script>


<!-- 还可以优化一下写法(了解-无需写-因为jQ内部这端代码已经帮助我们封装了) -->
<script type="text/javascript">
    function nihao(data) {
     
     
        console.log(data)
    }

    // 动态创建script发送的请求就是异步的
    // 动态创建一个script标签,通过他的src属性发送请求,然后把标签添加页码中,然后定义回调函数
    var script = document.createElement('script')
    script.src = 'http://123.57.109.30:3006/api/jsonp?callback=nihao&uname=lisi&age=12'
    // 把动态创建的script标签追加到head标签里面
    var head = document.getElementsByTagName('head')[0]
    head.appendChild(script)
    // 请求发送完成后再把刚刚创建的标签删除了
    head.removeChild(script)
</script>
  • 所以后端给了我一个地址, 让我传递一个方法名过去
    • 后端通过这个方法名(), 把值放入进去, 形成一个字符串, 返回到script标签地方加载, 执行了当前页面的函数并传值

11.2 jQ - 对jsonp的支持

  • $.ajax() 该方法可以发送jsonp请求,jsonp请求本质上不是Ajax
<script>
    $.ajax({
    
    
    // 请求地址
    url: 'http://123.57.109.30:3006/api/jsonp',
    // 服务端返回的数据格式:json(默认)/text/jsonp
    dataType: 'jsonp',
    // 回调函数
    success: function (data) {
    
    
        console.log(data)
    }
})
</script>

在这里插入图片描述

  • 所以Ajax创建了一次script的src请求, 内部自己带上了callback的key名字, 以及自己内部生成的方法名jQuery35107700325141788553_1606362547035
  • _ 对应的值是一个时间戳 (防止浏览器缓存)

假如后台的jsonp的参数名, 不叫callback怎么办?, 叫cb, 那么用jQ默认的就不行了

<script>
    $.ajax({
    
    
    // 请求地址
    url: 'http://123.57.109.30:3006/api/jsonp2',
    // 服务端返回的数据格式:json(默认)/text/jsonp
    dataType: 'jsonp',
    jsonp: "cb",
    // 回调函数
    success: function (data) {
    
    
        console.log(data)
    }
})
</script>

jsonp的缺点

  • 仅支持get请求,不支持其他请求方式
    • script标签发出请求本身就是get,不支持别的请求方式
    • get请求传递的数据量有限制(URL地址的长度不超过8000个字符)
    • post请求可以传递更多数据(post用请求体方式传递)
    • 如果确实希望跨域post提交数据,怎么办?让后端去做CORS

11.3 跨域解决方案 - cors

  • cors(纯粹的后端技术)- 前端啥也不用干直接请求 - 常用
    • 如果后端实现了cors配置,那么前端就可以直接跨域获取对应的数据
// 只需要后端开启 - 演示下即可
// 允许跨域资源共享 - nodejs 后端代码 - 前端不用写
const cors = require('cors')
app.use(cors())
  • 前端正常请求即可
// 现代浏览器默认已经支持跨域访问了, 再Ajax请求url前, 浏览器会先去后端请求一次, 看看后端是否支持cors方式(需要后端开启), 如果支持则保留这次请求的结果返回到回调函数, 否则舍弃掉所有数据直接报错
$.ajax({
    
    
    url: "http://123.57.109.30:3006/api/getbooks",
    type: "GET",
    success (res) {
    
    
        console.log(res);
    }
})

在这里插入图片描述

在这里插入图片描述

11.4 跨域解决 - 服务器反向代理

  • 刚刚我们请求的都是自己后端的接口, 现在请求网易新闻的接口
      1. 前端和网易新闻的域名不一致, 发生跨域访问, 默认被浏览器禁止掉
      1. 想使用jsonp方式, 但是你没办法去改人家网易的代码啊
      1. 所以采用反向代理, 找一个自己能控制的服务器(服务器去请求接口数据是可以的, 作为代理人, 前端请求自己的后端, 让后端作为代理人把数据拿回来返回给自己)

前提: 我知道别人的url可以拿到数据(注意在地址栏直接请求不算Ajax吧? 所以不会被浏览器禁止掉), 但是想用Ajax把数据请求回来铺设到自己的页面上 - 这个时候, 可以来个中介(自己能控制的服务器) 因为服务器之间请求是没有跨域限制的

// 如果后端不是我们自己的, 例如网页新闻接口(不能要求后端开启跨域)
// 我们可以自己弄一个服务器(用服务器作为代理人请求到数据, 自己服务器开启cors)
// 前端请求自己的服务器接口 - 把数据拿回来
$.ajax({
    
    
    url: "http://123.57.109.30:3006/api/163news",
    success (res) {
    
    
        console.log(res);
    }
})

12. axios

axios介绍

  • axios 是一个专门用于调用后台接口的js库,后续Vue和React环境都可以使用它
    • 支持客户端发送Ajax请求
    • 支持服务端Node.js发送请求
    • 支持Promise相关用法(解决回调地狱问题)
    • 支持请求和响应的拦截器功能(登录时会用到)
    • 可以手动取消请求
    • 自动转换JSON数据(JSON.parse(res))
    • 可以更加安全的处理请求

12.0 基本用法

  • 用axios替代jQuery实现get和post方式请求
// 1. axios - get方式 - 查询书籍信息
axios({
    
    
    method: 'get',
    url: 'http://123.57.109.30:3006/api/getbooks',
    params: {
    
    
        id: 1,
        bookname: '西游记'
    }
}).then(function (res) {
    
    
    console.log(res)
})


// 2. axios - post方式 - 新增书籍功能
document.getElementById("add").onclick = function () {
    
    
    axios({
    
    
        // 表示请求方式
        method: 'post',
        url: 'http://123.57.109.30:3006/api/addbook',
        data: {
    
    
            author: 'axios',
            bookname: 'axios从入门到真香',
            publisher: '自己出版的',
            appkey: '7250d3eb-18e1-41bc-8bb2-11483665535a'
        }
    }).then(function (res) {
    
    
        console.log(res)
    })
}

12.1 提交二进制数据

var myFile = document.getElementById("myFile");
var btn = document.getElementById("btn");

btn.onclick = function () {
    
    
    var fd = new FormData();
    fd.append("img", myFile.files[0]);
    fd.append('uname', 'lisi')
    fd.append('pwd', '123')
    axios({
    
    
        // 表示请求方式
        method: 'post',
        url: 'http://123.57.109.30:3006/api/upload/avatar',
        data: fd
    }).then(function (res) {
    
    
        console.log(res)
    })
}

12.2 全局默认配置

  • 配置基准URL地址
    • 做项目时,基准一般配置一次即可,发送请求时找到url后面的路径即可
axios.defaults.baseURL = 'http://123.57.109.30:3006'
// 7250d3eb-18e1-41bc-8bb2-11483665535a
// 1. axios - get方式访问
axios({
    
    
    // 表示请求方式
    method: 'get',
    url: '/api/getbooks',
    params: {
    
    
        id: 1,
        bookname: '西游记'
    }
}).then(function (res) {
    
    
    console.log(res)
})


// 2. axios - post方式 - 新增书籍功能
document.getElementById("add").onclick = function () {
    
    
    axios({
    
    
        // 表示请求方式
        method: 'post',
        url: '/api/addbook',
        data: {
    
    
            author: 'axios',
            bookname: 'axios从入门到真香',
            publisher: '自己出版的',
            appkey: '7250d3eb-18e1-41bc-8bb2-11483665535a'
        }
    }).then(function (res) {
    
    
        console.log(res)
    })
}

POST_请求参数格式总结

  • application/x-www-form-urlencoded
    • 表单的默认提交方式
    • $.ajax的post默认提交方式
  • multipart/form-data;
    • 支持文件上传:new FormData()
    • 也支持普通数据的提交,但是需要后端支持
  • application/json
    • 前端可以传递JSON字符串给后端

13. 异步编程

异步的概念

Ajax发送请求,浏览器不会阻塞(原因:内部采用了异步的方式发送请求)

  • 如何理解同步和异步的概念

    • 这两个概念是相对两个参与者来说的
  • 思考如下的场景:你的同学(A)正在寝室玩游戏,你(B)在门口喊他去吃饭

    • 场景一:A喊B去吃饭,B说等我一会,马上就结束了,此时A一直在门口等着,等B结束后,他们两个一块去食堂吃饭。(同步的,A阻塞了)
    • 场景二:A喊B去吃饭,B说等我一会,马上就结束了,此时A说饿的顶不住了,我先去,待会你去找我,我在某一个桌位等你,然后B结束后去指定的位置找A。(异步的,A没有阻塞)
  • 浏览器向服务器发送一个请求

    • 场景一:浏览器向服务器发请求,服务器需要返回信息,如果服务器尚未返回信息,浏览器如果一直等着服务器返回,什么事情也不做(阻塞的)。(同步)
    • 场景二:浏览器向服务器发请求,服务器需要返回信息,如果浏览器发出请求后,接着做别的事情,服务器返回信息后,才去通知浏览器进行处理,这种模式浏览器不阻塞。(异步)

13.0 异步数据获取方式

  • 获取异步结果的问题:无法通过返回值得到异步的结果
console.log(123); // 先执行
setTimeout(function () {
    
     // 注册定时器 - 最后执行
    console.log("我是2秒后的异步代码");
}, 0);

var xhr = new XMLHttpRequest()
xhr.open('get', 'http://123.57.109.30:3006/api/getbooks')
xhr.send()
xhr.onreadystatechange = function () {
    
     // 注册事件
    if (xhr.readyState === 4 && xhr.status === 200) {
    
    
        console.log(xhr.responseText);
    }
}

console.log(456); // 主线程执行完毕

// 先确定作用域 - 变量提升 - 然后主线程执行
// 定时器最后执行  (事件函数要被触发-点击事件/Ajax请求事件)

13.1 异步返回结果正确姿势:回调函数

function myAjax(fn) {
    
    
    var xhr = new XMLHttpRequest()
    xhr.open('get', 'http://123.57.109.30:3006/api/getbooks')
    xhr.send()
    xhr.onreadystatechange = function () {
    
     // 注册事件
        if (xhr.readyState === 4 && xhr.status === 200) {
    
    
            fn(JSON.parse(xhr.responseText));
        }
    }
}

myAjax(function(value){
    
     // 空手进去, 满载而归
    console.log(value);
})
  • 案例补充 - 定时器返回数据 - return不出来了 - 就用回调函数
// 要求:定义一个函数,函数内部一份数据,要求一秒后从函数外得到
function getData (callback) {
    
    
  var data = 'hello'
  setTimeout(function () {
    
    
    callback(data)
  }, 3000)
}

getData(function (data) {
    
    
  console.log(data)
})

异步原理分析

  • JavaScript的运行是单线程的
  • 为了防止单线程阻塞的问题,引入了事件队列(任务队列)机制
  • 什么样的任务进入事件队列
    • Ajax的回调函数(服务器有数据返回时:readyState发生变化时触发)
    • 定时函数(满足延时时间后触发,但是不一定触发)
    • 事件处理函数(特定事件发生时触发)
  • 任务队列中的任务何时触发?
    • 主线程必须是空闲的
    • 特定条件触发

在这里插入图片描述

13.2 异步回调的嵌套问题

  • 理解回调地狱的现象
function myAjax(url, data, fn){
    
    
    $.ajax({
    
    
        url: url,
        data: data,
        dataType: "json",
        success (res) {
    
    
            fn(res)
        }
    })
}

myAjax("http://123.57.109.30:3000/api/categoryFirst", {
    
    }, function(obj){
    
    
    var fId = obj['list'][0]['firstId'];
    myAjax("http://123.57.109.30:3000/api/categorySecond", {
    
    firstId: fId}, function(obj2){
    
    
        var sId = obj2['list'][0]['secondId'];
        myAjax("http://123.57.109.30:3000/api/categoryThird", {
    
    secondId: sId}, function(obj3){
    
    
            var tId = obj3['list'][0]['thiredId'];
            myAjax("http://123.57.109.30:3000/api/goodslist", {
    
    thirdId: tId}, function(obj4){
    
    
                console.log(obj4);
            })
        })
    })
})  
  • vue基础会学习Promise的用法 - 解决回调地域(把异步代码同步化)

在这里插入图片描述

14. 淘宝搜索案例

  • 案例图示如下所示

在这里插入图片描述

14.0 案例 - 获取联想菜单

  • 绑定输入事件并获取输入的值
// 1. 根据输入框的值 - 获取联想菜单
$("#ipt").on("input", function () {
    
    
    var kw = $(this).val();
    $.ajax({
    
    
        // 请求地址
        url: 'https://suggest.taobao.com/sug?q=' + encodeURI(kw),
        // 返回数据格式
        dataType: 'jsonp',
        // 回调函数
        success: function (data) {
    
    
            $("#suggest-list").empty();
            data.result.forEach(function(arr, index){
    
    
                var theDiv = `<div class="suggest-item">${
      
      arr[0]}</div>`;
                $("#suggest-list").append(theDiv);
            })
            $("#suggest-list").show();
        }
    })
})

14.1 防抖函数使用

定时n秒, 到了才执行逻辑代码, 如果事件又触发了, 清除上一个定时器, 重新创建定时器 最后执行一次

// 1. 定时器
var timer = null;

// 根据输入框的值 - 获取联想菜单 
$("#ipt").on("input", function () {
    
    
    var kw = $(this).val();
    // 2. 触发一次事件, 清空定时器 - 重新赋予一个(相当于重新计时)
    clearTimeout(timer);
    // 3. 如果不在触发事件, 那么3秒后执行逻辑代码
    timer = setTimeout(function () {
    
    
        $.ajax({
    
    
            // 请求地址
            url: 'http://123.57.109.30:3006/api/sug?q=' + encodeURI(kw),
            // 返回数据格式
            // 回调函数
            success: function (data) {
    
    
                $("#suggest-list").empty();
                data.result.forEach(function (arr, index) {
    
    
                    var theDiv = `<div class="suggest-item">${
      
      arr[0]}</div>`;
                    $("#suggest-list").append(theDiv);
                })
                $("#suggest-list").show();
            }
        })
    }, 300);
});

14.2 缓存搜索结果

在程序运行期间, 用一个对象变量来保存搜索过的联想菜单关键字 - 下次再输入相同的直接用变量里, 而不用再去请求了

// 定时器
var timer = null;
// 1. 定义缓存对象
var obj = {
    
    };

// 根据输入框的值 - 获取联想菜单 
$("#ipt").on("input", function () {
    
    
    var kw = $(this).val();
    clearTimeout(timer);
    timer = setTimeout(function () {
    
    
        // 2. 判断如果对象里有那个数据, 直接使用铺设页面
        if (obj[kw] !== undefined) {
    
    
            $("#suggest-list").empty();
            obj[kw].result.forEach(function (arr, index) {
    
    
                var theDiv = `<div class="suggest-item">${
      
      arr[0]}</div>`;
                $("#suggest-list").append(theDiv);
            })
            $("#suggest-list").show();
        } else {
    
    
            $.ajax({
    
    
                // 请求地址
                url: 'http://123.57.109.30:3006/api/sug?q=' + encodeURI(kw),
                // 返回数据格式
                // 回调函数
                success: function (data) {
    
    
                    $("#suggest-list").empty();
                    obj[kw] = data; // 3. 新的数据保存在逻辑变量obj上
                    data.result.forEach(function (arr, index) {
    
    
                        var theDiv = `<div class="suggest-item">${
      
      arr[0]}</div>`;
                        $("#suggest-list").append(theDiv);
                    })
                    $("#suggest-list").show();
                }
            })
        }
    }, 300);
});

14.3 防抖函数 - 封装

// 定义缓存对象
var obj = {
    
    };

// 根据输入框的值 - 获取联想菜单 
$("#ipt").on("input", debounce(function () {
    
    
    var kw = $(this).val();

    // 判断如果对象里有那个数据, 直接使用铺设页面
    if (obj[kw] !== undefined) {
    
    
        $("#suggest-list").empty();
        obj[kw].result.forEach(function (arr, index) {
    
    
            var theDiv = `<div class="suggest-item">${
      
      arr[0]}</div>`;
            $("#suggest-list").append(theDiv);
        })
        $("#suggest-list").show();
    } else {
    
    
        $.ajax({
    
    
            // 请求地址
            url: 'http://123.57.109.30:3006/api/sug?q=' + encodeURI(kw),
            // 返回数据格式
            // 回调函数
            success: function (data) {
    
    
                $("#suggest-list").empty();
                obj[kw] = data; // 新的数据保存在逻辑变量obj上
                data.result.forEach(function (arr, index) {
    
    
                    var theDiv = `<div class="suggest-item">${
      
      arr[0]}</div>`;
                    $("#suggest-list").append(theDiv);
                })
                $("#suggest-list").show();
            }
        })
    }
}, 300));

// 2. 定义防抖的函数
function debounce(fn, theTime) {
    
    
    return function () {
    
    
        clearTimeout(fn.timer);
        fn.timer = setTimeout(() => {
    
    
            fn.call(this, ...arguments);
        }, theTime);
    }
}

15. 协议加强

这里是概念, 了解即可

15.0 什么是通信

通信, 就是信息的传递交换

三要素:

  • 通信的主体: 客户端(浏览器) 和 服务器
  • 通信的内容: 客户端把内容 发给 服务器 / 服务器 返回内容给客户端
  • 通信的方式: http通信协议

15.1 通信协议

协议:规定(规则)

  • 通信主体双方 - 事先约定好的通信格式(内容格式) - 就叫做通信协议

15.2 http协议

通信的协议有很多种, 而http只是其中一种

HTTP HyperText Transfer Protocol 超文本传输协议 (浏览器和服务器之间传输的都叫超级文本(标签文本)

网页内容的传输 - 要遵守http协议的内容格式

  • 它的交互模型是 请求 和 响应 的 一去一回的 动作

15.3 URL地址补充

如果想用http协议, 去请求一个服务器, 要先知道你要请求的服务器的地址:功能版本号, 功能路径等

URL地址补充

在这里插入图片描述

  • URL的基本组成 schema://host:port/path?query#fragment
    • schema 协议:http/https/file/ftp/smtp/pop3
    • host 主机名(域名或者IP地址)IP(61.135.169.125)
      • 用来唯一的区分互联网中某台计算机
      • IP地址不好记住,所有有了域名
    • port 端口,http协议的默认端口是80,作用:区分计算机中某个应用程序(0-65535)
    • path 路径, /a/b/c/c 用来区分不同的资源 (与文件夹类似)
    • query 查询字符串,uname=lisi&age=12 主要用于传递get参数
    • fragment 锚点(hash 哈希),跳转到页面的某个位置
  • 通过什么规则, 找到哪台电脑里的哪个应用程序, 路径下的某个功能, 以及给它传参

15.4 请求消息(报文)

由客户端, 发送的数据信息, 就叫请求消息(请求报文)

在这里插入图片描述

请求对象例子: (可以在浏览器发起ajax请求后) 在这里查看

在这里插入图片描述

1. POST /work/1.php HTTP1.1
2. Host:www.wrox.com
3. User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET 
CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
4. Content-Type:application/x-www-form-urlencoded
5. Content-Length:40
6. Connection: Keep-Alive
7. 
8. name=Professional_Ajax&publisher=Wiley&page=1
  1. 1行代码, 请求方法(POST), URL(/work/1.php), 协议版本HTTP1.1
  2. 2, 3, 4, 5, 6行代码, 请求头代码, 头部字段名: 对应的值
  3. 7行代码, 代表空行 (必须有的), 规定
  4. 8行代码, 请求发送的数据 (请求体) - body体

这是客户端 -> 服务器 发送数据

前端发给后台数据的方式: get(在url后面拼接要传递的参数), post(在body体力传输参数给后台), 请求头(设置请求头传递参数)

15.4.0 请求头

  • User-Agent (浏览器相关信息 - 用户代理字符串)
  • Content-Length (请求发送的参数内容长度)
  • Content-Type (发送的参数内容的类型)
  • Accept (客户端能够接受什么类型的数据作为返回内容)

15.4.1 请求体

GET方式没有请求体 / POST才有请求体

15.5 响应消息(报文)

在这里插入图片描述

在浏览器里观察响应头字段的值 -

在这里插入图片描述

响应对象例子:

1. HTTP/1.1 200 OK
2. Date: Fri, 22 May 2009 06:07:21 GMT
3. Content-Type: text/html; charset=UTF-8
4. 
5. <html>
      <head></head>
      <body>
            <!--body goes here-->
      </body>
    </html>
  1. 1行代码, 响应状态行, 协议, 响应状态码, 响应状态消息
  2. 2, 3行, 消息报头, 服务端返回给客户端使用的一些消息
  3. 4行, 空行(规定)
  4. 5行, 服务器给客户端/浏览器, 返回的正文数据

这是客户端 <- 服务器 返回的数据

15.5.0 响应头

Access-Control-Allow-Origin: * - 服务器允许哪写地址链接(跨域 请求)

Date: 服务器上现在的时间

Content-Type: 响应内容类型

Content-Length: 响应内容的大小

15.5.1 响应体

就是后台返回的内容类型

html标签字符串 / JSON字符串数据 / css代码 / js代码 / 图片 / …

15.6 请求方式

  • 对服务器资源进行的操作
    • 增删改查(CRUD-create-read-update-delete)
    • 规范的接口设计会明确告诉你使用哪种请求方式
      • GET 查询
      • POST 添加
      • PUT 修改
      • DELETE 删除

在这里插入图片描述

  • Restfull 形式的URL(相同的地址, 不同的方式对应不同的功能)
    • http://abc.com/books GET 查询所有的图书列表
    • http://abc.com/books POST 添加一本图书
    • http://abc.com/books/123 DELTE 删除一本书(删除id是123的图书)
    • http://abc.com/books/123 PUT 修改一本图书的信息(修改id是123的图书信息)
    • http://abc.com/books/123/comment/456 DELETE (删除id是123的图书的id是456的评论信息)

15.7 响应状态码

  • 标识服务端响应的状态(服务器告诉客户端请求响应的结果是什么情况)

在这里插入图片描述

  • 2XX 表示服务端返回的数据是正常的(常见的是200)
  • 4XX 客户端发生了错误,因为服务器对应的资源不存在(常见的是404)
  • 5XX 服务器发生错误,服务器代码出错了(常见的是503)
  • 3XX 重定向,服务器收到请求后,返回一个地址,让浏览器重新请求到另外一个地址 (这种是后台返回一个状态码304, 前端就会调用本地保存的缓存)

15.7.0 2xx

客户端相关成功的状态码

  • 200 - 请求完全成功
  • 201 - 服务器上已经创建了这个资源

15.7.1 3xx

客户端相关的状态码

在这里插入图片描述

15.7.2 4xx

客户端相关的错误状态码

在这里插入图片描述

15.7.3 5xx

服务器端相关的状态码

在这里插入图片描述

经验值

前端发送jsonp请求调用后台接口

  • 前端发送请求调用jsonp接口,并且在浏览器的调试工具中能够看到数据返回了,格式(json)如下所示
  • 但是在success中没有得到数据,为什么?因为接口有问题
  • jsonp接口应该返回什么?函数调用

在这里插入图片描述

  • 如何解决问题?
    • 方法一:后端把接口调整为jsonp接口
    • 方法二:后端配置cors,前端使用Ajax发请求

跨域Ajax接口的报错问题

  • 如果Ajax调用的后端接口跨域了,并且后端没有解决跨域问题,那么前端就会报错

在这里插入图片描述

  • 解决方案:让后端解决CORS或者反向代理;采用jsonp接口方案

如有不足,请多指教,
未完待续,持续更新!
大家一起进步!

猜你喜欢

转载自blog.csdn.net/qq_40440961/article/details/111597126