数据交互 Ajax

1、客户端与服务器


1.1、什么是客户端与服务器?

客户端:在因特网中,负责获取和消费资源的电脑

服务器:在因特网中,负责存放和对外提供资源的电脑

在这里插入图片描述

在个人的电脑中,通过安装浏览器的形式,访问服务器对外提供的各种资源

服务器的本质就是一台电脑,只不过,它的综合性能要比个人电脑强很多!

客户端与服务器之间的通信过程,分为 请求 --> 处理 --> 响应 三个步骤

网页中的每一个资源,都是通过 请求 --> 处理 --> 响应 的方式从服务器获取回来的

1.2、URL地址

URL(全称是Uniform Resource Locator)中文叫统一资源定位符,用于标识互联网上每个资源的唯一存放位置。浏览器只有通过URL地址,才能正确定位资源的存放位置,从而成功访问到对应的资源

常见的URL:

  • https://www.taobao.com/
  • https://www.baidu.com/
  • https://www.hua.com/
  • ……
URL地址的组成部分

URL地址一般由三部分组成:

在这里插入图片描述

  • 客户端与服务器之间的通信协议
  • 存有该资源的服务器名称
  • 资源在服务器上具体的存放位置

服务器对外提供哪些资源?

  • 视频、音频、图片、文本内容、数据

网页中的数据,也是服务器对外提供的一种资源

  • HTML 骨架
  • CSS 颜值
  • Javascript 行为
  • 数据 灵魂

骨架、颜值、行为皆为数据服务,数据,在网页中无处不在

网页中如何请求数据?

如果要在网页中请求服务器上的数据资源,则需要用到 XMLHttpRequest 对象。 XMLHttpRequest(简称 xhr)是浏览器提供的 js 成员,通过它可以请求服务器上的数据资源

数据,也是服务器对外提供的一种资源。只要是资源,必然要通过 请求 --> 处理 --> 响应 的方式进行获取

在这里插入图片描述

1.3、资源的请求方式

客户端请求服务器时,请求的方式有很多种,最常见的两种请求方式分别为 get 和 post 请求

get 请求通常用于获取服务端资源(向服务器要资源)

  • 根据 URL 地址,从服务器获取 HTML 文件、css 文件、js文件、图片文件、数据资源等

post 请求通常用于向服务器提交数据(往服务器发送资源)

  • 登录时向服务器提交的登录信息、注册时向服务器提交的注册信息等各种数据提交操作

2、XMLHttpRequest


2.1、什么是XMLHttpRequest ?

XMLHttpRequest (简称xhr)是浏览器提供的Javascript 对象,通过它可以请求服务器上的数据资源。jQuery中的Ajax函数,就是基于xhr对象封装出来的

2.2、基于xhr发送GET请求

基于xhr发送请求四步走:

  1. 创建xhr对象
  2. 调用xhr.open()函数
  3. 调用xhr.send()函数
  4. 监听 xhr.onreadystatechange 事件
<script>
    // 1.创建 xhr 对象
    let xhr = new XMLHttpRequest()
    // 2.调用 open 函数,指定 请求方式与请求地址
    let id = 1
    let uname = "小白"
    xhr.open("GET", `http://localhost:8086/api/getComment?id=${id}&name=${uname}`)
    // 3.调用 send 函数
    xhr.send()
    // 4.监听 onreadystatechange 事件
    xhr.onreadystatechange = function () {
        // 监听 xhr 对象的请求状态 readystate 与服务器响应的状态 status
        if (xhr.readyState === 4 && xhr.status === 200) {
            // 获取服务器响应的数据
            console.log(xhr.responseText)
        }
    }
</script>
xhr对象的readystate属性

XMLHttpRequest对象的readyState属性,用来表示当前Ajax请求所处的状态。每个Ajax请求必然处于以下状态中的一个

状态描述
0UNSETxhr对象已被创建,但尚未调用open方法(未初始化)
1OPENEDopen() 方法已被调用,但尚未发送请求(载入)
2HEADERS_RECEIVED请求已经发送完成(载入完成)
3LOADING接收到部分响应数据(交互)
4DONE已经接收到了全部数据,并且连接已经关闭(完成)
查询字符串

查询字符串(URL 参数)是指在URL的末尾加上用于向服务器发送信息的字符串(变量)

格式:键=值&中间用&符号分割 第一个使用?

URL编码与解码

URL地址中,只允许出现英文相关的字母、标点符号、数字,因此,在URL地址中不允许出现中文字符

如果URL中需要包含中文这样的字符,则必须对中文字符进行编码(转义)

URL编码原则:使用安全的字符(没有特殊用途或无特殊意义的可打印字符)去表示那些不安全的字符,也就是使用英文字符去表示非英文字符

浏览器提供了URL编码与解码的API,分别是:

  • encodeURI() 编码函数
  • decodeURI() 解码函数
<script>
    let name = "小白"
    // 编码
    let encodeStr = encodeURI(name)
    console.log(encodeStr)

    // 解码
    let decodeStr = decodeURI("%E5%B0%8F%E7%99%BD")
    console.log(decodeStr)
</script>

由于浏览器会自动对URL地址进行编码操作,因此,大多数情况下,是不需要关心URL地址的编码

2.3、基于xhr发送POST请求

<script>
    // 1.创建 xhr 对象
    let xhr = new XMLHttpRequest()
    // 2.调用 open 函数,指定 请求方式与请求地址
    xhr.open("POST", "http://localhost:8086/api/addComment")
    // 3.设置Content-Type属性
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
    // 4.调用 send 函数
    xhr.send(`title=今天真是个好天气&author=xxx`)
    // 5.监听 onreadystatechange 事件
    xhr.onreadystatechange = function () {
        // 监听 xhr 对象的请求状态 readystate 与服务器响应的状态 status
        if (xhr.readyState === 4 && xhr.status === 200) {
            // 获取服务器响应的数据
            console.log(xhr.responseText)
        }
    }
</script>
数据交互格式

数据交换格式,就是服务器端与客户端之间进行数据传输与交换的格式

常用的两种数据交换格式分别是XML和JSON。其中XML用的较少,最为流行使用的数据交换格式就是JSON

XML
<comment>
    <title>必属精品</title>
    <author>who am i</author>
</comment>
  • XML格式臃肿,和数据无关的代码多,体积较大,传输效率低
  • 解析XML比较麻烦
JSON

JSON就是Javascript对象和数组的字符串表示法,它使用文本表示一个JS对象或数组的信息,因此,JSON的本质是字符串

作用:JSON 是一种轻量级的文本数据交换格式,在作用上类似于XML,专门用于存储和传输数据,但是JSON比XML更小、更快、更易解析

JSON两种结构

对象结构:对象结构在JSON中表示为{}括起来的内容。数据结构为{ key: value, key: value, … }的键值对结构。其中,key必须是使用英文的双引号包裹的字符串,value 的数据类型可以是数字、字符串、布尔值、null、数组、对象6种类型

<script>
    let user = {
        "uname": "小白",
        "age": 22,
        "email": "xiaobai@qq.com",
        "hobbies": ["code", "swim", "girl"],
    }
</script>

数组结构:数组结构在JSON中表示为[]括起来的内容。数据结构为[ “java”, “javascript”, 30, true …数组中数据的类型可以是数字、字符串、布尔值、null、数组、对象6种类型

<script>
    let user = {
        "uname": "小白",
        "age": 22,
        "email": "xiaobai@qq.com",
        "hobbies": ["code", "swim", "girl"],
        "address": [
            {
                "province": "湖北省",
                "city": "武汉市",
            },
            {
                "province": "河南省",
                "city": "洛阳市",
            }
        ]
    }
</script>

注:

  • 属性名必须使用双引号包裹
  • 字符串类型的值必须使用双引号包裹,JSON中不允许使用单引号表示字符串
  • JSON中不能写注释
  • JSON的最外层必须是对象或数组格式
  • 不能使用undefined或函数作为JSON的值

JSON和JS对象互转

JS对象转JSON字符串:JSON.stringify(JS对象)

JSON字符串转JS对象:JSON.parse(JS字符串)

<script>
    let userObj = {
        uname: '小白',
        age: 22,
        email: 'xiaobai@qq.com',
        hobbies: ['code', 'swim', 'girl'],
        address: [
            {
                province: '湖北省',
                city: '武汉市',
            },
            {
                province: '河南省',
                city: '洛阳市',
            }
        ]
    }

    // JS对象转JSON字符串
    let userStr = JSON.stringify(userObj)
    console.log(userStr)

    // JSON字符串转JS对象
    let obj = JSON.parse(userStr)
    console.log(obj)
</script>

2.4、XMLHttpRequest Level2新特性

旧版XMLHttpRequest的缺点

  • 只支持文本数据的传输,无法用来读取和上传文件
  • 传送和接收数据时,没有进度信息,只能提示有没有完成
XMLHttpRequest Level2新特性
  • 可以设置HTTP请求的时限
  • 可以使用FormData对象管理表单数据
  • 可以上传文件
  • 可以获得数据传输的进度信息
设置HTTP请求的时限

有时,Ajax操作很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久。新版本的XMLHttpRequest对象,增加了timeout属性,可以设置HTTP请求的时限

具体语法:xhr.timeout=3000

对应的回调函数:xhr.ontimeout

<script>
    let xhr = new XMLHttpRequest()
    // 设置超时时间
    xhr.timeout = 3000
    // 超时以后的处理函数
    xhr.ontimeout = function () {
        alert("请求超时 请稍后重试")
    }
    xhr.open("GET", "http://localhost:8086/api/getComment")
    xhr.send()
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.responseText)
        }
    }
</script>
FormDate对象管理表单数据

Ajax操作往往用来提交表单数据。为了方便表单处理,HTML5 新增了一个FormData对象,可以模拟表单操作:

<script>
    // 1.创建 FormData 对象
    let fd = new FormData()
    // 2.调用 append 函数,向 ds 追加数据
    fd.append("uname", "小黑")
    fd.append("upwd", "8848")
    // 3.创建 XHR 对象
    let xhr = new XMLHttpRequest()
    // 4.指定请求类型与URL地址
    xhr.open("POST", "http://localhost:8086/api/formData")
    // 5.提交 fd 对象,该方式与提交网页表单的效果完全一致
    xhr.send(fd)

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(JSON.parse(xhr.responseText))
        }
    }
</script>

FormData对象也可以用来获取网页表单的值

<form id="user-form">
    <label>
        用户名:
        <input type="text" name="uname" autocomplete="off">
    </label>
    <label>
        密码:
        <input type="password" name="upwd">
    </label>
    <input type="submit">
</form>

<script>
    let user_form = document.querySelector("#user-form")
    user_form.addEventListener("submit",  (e)=> {
        e.preventDefault()
        // 创建 FormData 快速获取 form 表单中的数据
        let fd = new FormData(user_form)
        let xhr = new XMLHttpRequest()
        xhr.open("POST", "http://localhost:8086/api/formData")
        xhr.send(fd)
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4 && xhr.status === 200) console.log(JSON.parse(xhr.responseText))
        }
    })
</script>
上传文件

新版XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件

<form>
    <input type="file" id="file">
    <button id="btnUpload">上传文件</button>
    <br>
    <p>
        <img src="" alt="" id="img">
    </p>
</form>

<script>
    document.querySelector("#btnUpload").addEventListener("click", (e) => {
        e.preventDefault()
        // 获取到选择的文件列表
        let files = document.querySelector("#file").files
        if (files.length <= 0) return alert("请选择要上传的文件")

        let fd = new FormData()
        // 将用户选择的文件 添加到 FormData 中
        fd.append("avatar", files[0])

        let xhr = new XMLHttpRequest()
        xhr.open("POST", "http://localhost:8086/api/upload")
        xhr.send(fd)

        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                let data = JSON.parse(xhr.responseText)
                if (data.status === 200) {
                    document.querySelector("#img").src = data.url
                } else {
                    // 上传失败
                    console.log('图片上传失败!' + data.message);
                }
            }
        }
    })
</script>
显示文件上传进度
<!-- panel 面板 -->
<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">上传文件</h3>
    </div>
    <div class="panel-body">
        <div class="row" style="height: 60px;">
            <div class="col-md-3">
                <input type="file" id="file" class="form-control">
            </div>

            <div class="col-md-3">
                <button id="btnUpload" class="btn btn-primary">上传文件</button>
            </div>
        </div>
        <div class="row">
            <!-- 进度条 -->
            <div class="progress" style="width: 600px;margin-left: 15px;">
                <div class="progress-bar progress-bar-striped active" style="width: 10%" id="percent">
                    10%
                </div>
            </div>

            <!-- 图片 -->
            <div class="col-xs-6 col-md-3">
                <a href="#" class="thumbnail">
                    <img src="" alt="..." id="img">
                </a>
            </div>
        </div>
    </div>
</div>

<script>
    document.querySelector("#btnUpload").addEventListener("click", (e) => {
        e.preventDefault()
        // 获取到选择的文件列表
        let files = document.querySelector("#file").files
        if (files.length <= 0) return alert("请选择要上传的文件")

        let fd = new FormData()
        // 将用户选择的文件 添加到 FormData 中
        fd.append("avatar", files[0])

        let xhr = new XMLHttpRequest()
        // 监听文件上传进度
        xhr.upload.onprogress = function (e) {
            if (e.lengthComputable) {
                let progress = Math.ceil((e.loaded / e.total) * 100)
                // 动态设置进度条
                document.querySelector("#percent").style.width = progress + "%"
                document.querySelector("#percent").innerHTML = progress + "%"
                // console.log(progress)
            }
        }
        // 监听上传完成的事件
        xhr.upload.onload = function () {
            document.querySelector("#percent").classList.remove("progress-bar-striped")
            document.querySelector("#percent").classList.add("progress-bar-success")
        }

        xhr.open("POST", "http://localhost:8086/api/upload")
        xhr.send(fd)

        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                let data = JSON.parse(xhr.responseText)
                if (data.status === 200) {
                    document.querySelector("#img").src = data.url
                } else {
                    // 上传失败
                    console.log('图片上传失败!' + data.message);
                }
            }
        }
    })
</script>
使用jQuery文件上传

ajaxStart(callback):Ajax请求开始时,执行ajaxStart函数。可以在ajaxStart的callback中显示loading效果

ajaxStop(callback):Ajax请求结束时,执行ajaxStop函数。可以在ajaxStop的callback中隐藏loading效果

注:jQuery版本1.8之后,上述方法只能被附加到文档上

<body style="padding: 15px;">
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3 class="panel-title">文件上传</h3>
        </div>
        <div class="panel-body">
            <div class="row" style="height: 60px;">
                <div class="col-md-3">
                    <input type="file" id="file" class="form-control">
                </div>
                <div class="col-md-6">
                    <button class="btn btn-primary" id="btnUpload">上传</button>
                </div>
            </div>
            <div class="row" style="height: 300px;">
                <div class="col-md-3">
                    <img src="./images/loading.gif" width="500" id="loading">
                </div>
                <div class="col-md-3">
                    <img src="#" class="img-circle" alt="Image" id="img">
                </div>
            </div>
        </div>
    </div>

    <script>
        $("#loading").hide()
        document.querySelector("#btnUpload").addEventListener("click", function () {
            let files = $("#file")[0].files
            if (files.length <= 0) {
                return alert("请选择文件后在上传")
            }

            let fd = new FormData()
            fd.append("avatar", files[0])

            // 监听到 Ajax 请求发起了
            $(document).ajaxStart(function () {
                $("#loading").show()
            })

            // 监听到 Ajax 请求完成之后
            $(document).ajaxStop(function () {
                $("#loading").hide()
            })

            $.ajax({
                method: "POST",
                url: "http://localhost:8086/api/upload",
                data: fd,
                // 不修改 Content-Type 属性,使用 FormData 默认的 Content-Type 值
                contentType: false,
                // 不对 FormData 中的数据进行 url 编码,而是将 FormData 数据原样发送到服务器
                processData: false,
                success: (resp) => {
                    console.log(resp)
                    $("#img").attr("src", resp.url)
                }
            })
        })
    </script>
</body>

3、Ajax与模板引擎


3.1、Ajax是什么?

Ajax 的全称是 Asynchronous Javascript And XML(异步 JavaScript 和 XML)

简单理解:在网页中利用 XMLHttpRequest 对象和服务器进行数据交互的方式,就是Ajax

Ajax可以让我们轻松实现网页与服务器之间的数据交互
在这里插入图片描述

应用场景:检测用户名是否被占用、百度搜索关键词提示、数据的增删改查

3.2、Ajax使用

浏览器中提供的 XMLHttpRequest 用法比较复杂,所以 jQuery 对 XMLHttpRequest 进行了封装,提供了一系列 Ajax 相关的函数,极大地降低了 Ajax 的使用难度

jQuery 中发起 Ajax 请求最常用的三个方法如下:

  • $.get()
  • $.post()
  • $.ajax()
$.get()
<script>
    document.querySelector("div").addEventListener("click", () => {
        $.get("http://localhost:8086/api/getGoods", { id: 1010 }, function (data) {
            if (data.status !== 200) {
                return alert("获取商品信息失败")
            }
            console.log(data)
        })
    })
</script>
$.post()
<script>
    document.querySelector("div").addEventListener("click", () => {
        $.post("http://localhost:8086/api/addGoods", { goodName: "小米手机", price: 1999, desc: "有点狠的真旗舰" }, function (data) {
            if (data.status !== 200) {
                return alert("添加商品信息失败")
            }
            console.log(data)
        })
    })
</script>
$.ajax()
<script>
    document.querySelector("div").addEventListener("click", () => {
        $.ajax({
            // 请求地址
            url: "http://localhost:8086/api/addGoods",
            // 请求方式
            method: "post",
            // 期待服务器返回的数据格式
            dataType: "json",
            // 请求参数
            data: { goodName: "红米K40", price: 1999, desc: "极致性价比" },
            // 成功
            success: (data) => {
                console.log(data)
            },
            error: () => {
                console.log("出错了")
            },
            // 头信息
            headers: {
                uname: "Mr zhang"
            },
            // 超时时间
            timeout: 3000
        })
    })
</script>
serialize()函数

为了简化表单中数据的获取操作,jQuery 提供了 serialize() 函数,语法格式:$(selector).serialize()

<script>
    document.querySelector("#formAddUser").addEventListener("submit", function (e) {
        console.log($(this).serialize())
        $.ajax({
            url: "http://localhost:8086/api/user",
            method: "post",
            dataType: "json",
            data: $(this).serialize(),
            success: (data) => {
                console.log(data)
            },
            error: () => {
                console.log("出错了")
            },
            timeout: 3000
        })
        e.preventDefault()
    })
</script>

serialize() 函数的好处:可以一次性获取到表单中的所有的数据

3.3、接口

使用 Ajax 请求数据时,被请求的 URL 地址,就叫做数据接口(简称接口)。同时,每个接口必须有请求方式

接口文档

接口文档可以包含很多信息,也可以按需进行精简,不过,一个合格的接口文档,应该包含以下6项内容,从而为接口的调用提供依据:

  • 接口名称:用来标识各个接口的简单说明,如登录接口,获取商品列表接口等
  • 接口URL:接口的调用地址
  • 调用方式:接口的调用方式,如 GET 或 POST
  • 参数格式:接口需要传递的参数,每个参数必须包含参数名称、参数类型、是否必选、参数说明这4项内容
  • 响应格式:接口的返回值的详细描述,一般包含数据名称、数据类型、说明3项内容
  • 返回示例(可选):通过对象的形式,例举服务器返回数据的结构

3.4、模板引擎

什么是模板引擎?

模板引擎,顾名思义,它可以根据程序员指定的模板结构和数据,自动生成一个完整的HTML页面

在这里插入图片描述

模板引擎的优点

  • 减少了字符串的拼接操作
  • 使代码结构更清晰
  • 使代码更易于阅读与维护
art-template

art-template 是一个简约、超快的模板引擎

官网地址

使用步骤

  • 导入 art-template
  • 定义数据
  • 定义模板
  • 调用 template 函数
  • 渲染HTML结构
<!-- 定义模板 -->
<script type="text/html" id="user-info">
        <p>姓名:{{uname}}</p>
        <p>年龄:{{age}}</p>
        <p>婚姻状态:{{if isMarry}}已婚{{else}}未婚{{/if}}</p>
        <p>出生日期:{{birthday | dateFormat 'yyyy-MM-dd hh:mm:ss'}}</p>
        爱好:
        <ul>
            {{each hobbies}}
            <li>{{$value}}</li>
        {{/each}}
    </ul>
</script>

<!-- 模板的 HTML 结构 必须定义到script中 -->
<script>
    let data = {
        uname: '小昭',
        age: 22,
        isMarry: false,
        birthday: new Date("2002-1-15"),
        hobbies: ['girl', 'code', 'swim']
    }

    // 过滤器定义
    template.defaults.imports.dateFormat = function (date) {
        let year = date.getFullYear()
        let month = date.getMonth() + 1
        let day = date.getDate()

        mouth = month < 10 ? "0" + month : month
        day = day < 10 ? "0" + day : day
        return `${year}-${mouth}-${day}`
    };

    // 调用 template 函数
    let html = template('user-info', data)
    // console.log(html)
    document.querySelector('.box').innerHTML = html
</script>

具体语法参考官方文档

4、跨域与JSONP


4.1、何为同源?

如果两个页面的协议,域名和端口都相同,则两个页面具有相同的源

举例:http://www.bd.com/index.html页面的同源检测

URL是否同源原因
http://www.bd.com/register.html同源(协议、域名、端口相同)
https://www.bd.com/about.html协议不同(http 与 https)
http://zhang.bd.com/index.html域名不同(www.bd.com 与 zhang.bd.com)
http://www.bd.com:8006/login.html端口不同(默认的 80 端口与 8006 端口)
http://www.bd.com:80/main.html同源(协议、域名、端口相同)

4.2、什么是同源策略?

同源策略(英文全称 Same origin policy)是浏览器提供的一个安全功能

浏览器规定,A 网站的 JavaScript,不允许和非同源的网站 B/C/D… 之间,进行资源的交互,例如:

  • 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
  • 无法接触非同源网页的DOM
  • 无法向非同源地址发送 Ajax 请求

4.3、什么是跨域?

同源指的是两个 URL 的协议、域名、端口一致,反之,则是跨域

出现跨域的根本原因:浏览器的同源策略不允许非同源的 URL 之间进行资源的交互

  • 网页:http://www.db.com/index.html
  • 接口:http://www.api.com/getUser
浏览器对跨域请求的拦截

在这里插入图片描述

注:浏览器允许发起跨域请求,但是,跨域请求回来的数据,会被浏览器拦截,无法被页面获取到!

如何实现跨域数据请求?

现如今,实现跨域数据请求,最主要的两种解决方案,分别是 JSONP 和 CORS

  • JSONP:诞生的早,兼容性好(兼容低版本IE)。是前端程序员为了解决跨域问题,被迫想出来的一种临时解决方案。缺点是只支持 GET 请求,不支持 POST 请求
  • CORS:出现的较晚,它是 W3C 标准,属于跨域 Ajax 请求的根本解决方案。支持 GET 和 POST 请求。缺点是不兼容某些低版本的浏览器
jQuery中的JSONP

jQuery 提供的 $.ajax() 函数,除了可以发起真正的 Ajax 数据请求之外,还可以发起 JSONP 数据请求

默认情况下,使用 jQuery 发起 JSONP 请求,会自动携带一个 callback=jQueryxxx 的参数,jQueryxxx 是随机生成的一个回调函数名称

在使用 jQuery 发起 JSONP 请求时,如果想要自定义 JSONP 的参数以及回调函数名称,可以通过如下两个参数来指定:

<script>
    // 出现跨域问题
    let keyword = "裤"
    // $.get(`https://suggest.taobao.com/sug?q=${keyword}`, function (resp) {
    //     console.log(resp)
    // })

    // 发起JSONP请求
    $.ajax({
        url: `https://suggest.taobao.com/sug?q=${keyword}`,
        // 表示要发送jsonp的数据请求
        dataType: "jsonp",
        // 发送到服务端的参数名称,默认值为 callback
        jsonp: 'callback',
        // 自定义的回调函数名称,默认值为 jQueryxxx 格式
        jsonpCallback: 'search',
        success: (resp) => {
            console.log(resp)
        }
    })
</script>
jQuery中JSONP的实现过程

jQuery 中的 JSONP,也是通过 <script> 标签的 src 属性实现跨域数据访问的,只不过,jQuery 采用的是动态创建和移除 <script> 标签的方式,来发起 JSONP 数据请求

  • 在发起 JSONP 请求的时候,动态向 <header> 中 append 一个 <script> 标签
  • 在 JSONP 请求成功以后,动态从 <header> 中移除刚才 append 进去的 <script> 标签

5、HTTP协议


5.1、何为通信?

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

通信三要素:

  • 通信的主体
  • 通信的内容
  • 通信的方式

现实生活中的通信

案例:张三要把自己考上清北的好消息写信告诉自己的好朋友李四

其中:通信的主体是张三和李四,通信的内容是考上清北;通信的方式是写信

互联网中的通信

案例:服务器把考上清北通过响应的方式发送给客户端浏览器

其中,通信的主体是服务器和客户端浏览器;通信的内容是考上清北;通信的方式是响应

5.2 、什么是通信协议?

通信协议(Communication Protocol)是指通信的双方完成通信所必须遵守的规则和约定

简单理解:通信双方采用约定好的格式来发送和接收消息,这种事先约定好的通信格式,就叫做通信协议

客户端与服务器之间要实现网页内容的传输,则通信的双方必须遵守网页内容的传输协议

网页内容又叫做超文本,因此网页内容的传输协议又叫做超文本传输协议(HyperText Transfer Protocol) ,简称 HTTP 协议

5.3、什么是HTTP协议?

HTTP 协议即超文本传送协议 (HyperText Transfer Protocol) ,它规定了客户端与服务器之间进行网页内容传输时,所必须遵守的传输格式

  • 客户端要以HTTP协议要求的格式把数据提交到服务器
  • 服务器要以HTTP协议要求的格式把内容响应给客户端
HTTP请求消息

由于 HTTP 协议属于客户端浏览器和服务器之间的通信协议。因此,客户端发起的请求叫做 HTTP 请求,客户端发送到服务器的消息,叫做 HTTP 请求消息,也叫做HTTP 请求报文

HTTP 请求消息由请求行(request line)、请求头部( header ) 、空行 和 请求体 4 个部分组成

在这里插入图片描述

请求行

请求行由请求方式、URL 和 HTTP 协议版本 3 个部分组成,它们之间使用空格隔开

请求头

请求头部用来描述客户端的基本信息,从而把客户端相关的信息告知服务器,请求头部由多行 键/值对 组成,每行的键和值之间用英文冒号分隔

  • User-Agent 用来说明当前是什么类型的浏览器
  • Content-Type 用来描述发送到服务器的数据格式
  • Accept 用来描述客户端能够接收什么类型的返回内容
  • Accept-Language 用来描述客户端期望接收哪种人类语言的文本内容

常见的请求头字段

头部字段说明
Host要请求的服务器域名
Connection客户端与服务器的连接方式(close 或 keepalive)
Content-Length用来描述请求体的大小
Accept客户端可识别的响应内容类型列表
User-Agent产生请求的浏览器类型
Content-Type客户端告诉服务器实际发送的数据类型
Accept-Encoding客户端可接收的内容压缩编码形式
Accept-Language用户期望获得的自然语言的优先顺序
空行

最后一个请求头字段的后面是一个空行,通知服务器请求头部至此结束

请求消息中的空行,用来分隔请求头部与请求体

请求体

请求体中存放的,是通过 POST 方式提交给服务器的数据

注:只有 POST 请求才有请求体,GET 请求是没有请求体的!

MDN 官方文档

HTTP响应消息

响应消息就是服务器响应给客户端的消息内容,也叫作响应报文

HTTP响应消息由响应状态行、响应头部、空行 和 响应体 4 个部分组成
在这里插入图片描述

响应状态行

状态行由 HTTP 协议版本、状态码和状态码的描述文本 3 个部分组成,他们之间使用空格隔开

响应头部

响应头部用来描述服务器的基本信息。响应头部由多行 键/值对 组成,每行的键和值之间用英文冒号分隔

空行

在最后一个响应头部字段结束之后,会紧跟一个空行,用来通知客户端响应头部至此结束。响应消息中的空行,用来分隔响应头部与响应体

响应体

响应体中存放的,是服务器响应给客户端的资源内容

HTTP请求方法

HTTP 请求方法,属于 HTTP 协议中的一部分,请求方法的作用是:用来表明要对服务器上的资源执行的操作。最常用的请求方法是 GET 和 POST

序号方法描述
1GET(查询)发送请求来获得服务器上的资源,请求体中不会包含请求数据,请求数据放在协议头中
2POST(新增)向服务器提交资源(例如提交表单或上传文件)。数据被包含在请求体中提交给服务器
3PUT(修改)向服务器提交资源,并使用提交的新资源,替换掉服务器对应的旧资源
4DELETE(删除)请求服务器删除指定的资源
5HEADHEAD 方法请求一个与 GET 请求的响应相同的响应,但没有响应体
6OPTIONS获取http服务器支持的http请求方法,允许客户端查看服务器的性能,比如ajax跨域时的预检等
7CONNECT建立一个到由目标资源标识的服务器的隧道
8TRACE沿着到目标资源的路径执行一个消息环回测试,主要用于测试或诊断
9PATCH是对 PUT 方法的补充,用来对已知资源进行局部更新
HTTP响应状态码

HTTP 响应状态码(HTTP Status Code),也属于 HTTP 协议的一部分,用来标识响应的状态

响应状态码会随着响应消息一起被发送至客户端浏览器,浏览器根据服务器返回的响应状态码,就能知道这次 HTTP 请求的结果是成功还是失败

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字用来对状态码进行细分

HTTP 状态码共分为 5 种类型:

分类分类描述
1**信息,服务器收到请求,需要请求者继续执行操作(实际开发中很少遇到 1 类型的状态码)
2**成功,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器在处理请求的过程中发生了错误
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值