• js网络编程


    AJAX

    AJAX异步JavaScript 和 XMLAsynchronous JavaScript And XML
    在网页中利用XMLHttpRequest对象和服务器进行数据交互的方式,就是AJAX
    AJAX本身不是一种新技术,而是将现有技术结合起来的方法
    具体来说,实现AJAX有两种方式

    XHR

    第一种则是通过XHR
    XHRXMLHTTPRequest,这是一个用于网络请求的对象,我们可以用它来发送和接收JSONXMLHTMLTEXT等类型的数据

    创建AJAX请求

    创建一个AJAX请求通常分为四步

    1. 创建XMLHTTPRequest
      const XHR = new XMLHttpRequest()
      
      • 1
    2. 监听onreadystatechange事件,这个事件将会在网络请求状态每次改变后执行
      XHR.onreadystatechange = function() {
      	console.log("状态发生了改变");
      }
      
      • 1
      • 2
      • 3
    3. 通过open方法配置网络请求
      XHR.open("get","")
      
      • 1
      open方法接收三个参数,第一个参数是请求类型,如getpostdelete等等,第二个参数为向其发送请求的URL,第三个参数为布尔类型的可选参数,表示是否为异步操作,默认为true
    4. 调用send方法发送请求
      XHR.send()
      
      • 1

    GET和POST传递参数

    通过GET请求来传递数据只能通过query参数

    XHR.open("get","http://localhost:8088/get?name=zhangsan&age=18")
    XHR.send()
    
    • 1
    • 2

    事实上GET请求并不适合传递数据,如果想要大量传递数据需要使用POST请求

    1. POST请求通过表单传递数据
      const form = document.querySelector("form")
      const formData = new FormData(form)
      XHR.open("post","http://localhost:8088/post")
      XHR.send(formData)
      
      • 1
      • 2
      • 3
      • 4
    2. 通过设置请求头application/x-www-form-urlencoded的方式
      XHR.open("post","http://localhost:8088/post")
      const data = "name=zhangsan&age=18"
      XHR.setRequestHeader("Content-type","application/x-www-form-urlencoded")
      XHR.send(data)
      
      • 1
      • 2
      • 3
      • 4
    3. 通过设置请求头application/json的方式
      XHR.open("post","http://localhost:8088/post")
      const data = JSON.stringify({name:"zhangsan",age:18})
      XHR.setRequestHeader("Content-type","application/json; charset=utf-8")
      XHR.send(data)
      
      • 1
      • 2
      • 3
      • 4

    XHR的state

    在一次网络请求中XHR的状态会发生很多次变化
    我们可以在onreadystatechange事件中通过XHR.readyState拿到每次状态变化的值

    状态码意义
    0请求被创建,但未调用open方法
    1open方法被调用
    2send方法被调用,并且头部和状态已可取得
    3下载中
    4下载操作已完成

    其他事件监听

    事件名作用
    loadstart请求开始
    progress第一个响应数据包到达
    abort调用了XHR.abort()取消了请求
    error发生连接错误
    load请求完成
    timeout请求超时,前提是设置了timeout
    loadend在load、error、timeout、abort之后触发

    响应数据和响应类型

    发送了请求过后我们可以通过response属性来获取返回的数据

    const res = XHR.response
    
    • 1

    返回数据的类型则是由responseType来决定

    XHR.responseType = "json"
    
    • 1

    如果responseType值为空则为默认值text
    responseText返回的是text数据
    responseXML返回的则是XML
    在早期的服务器中返回的数据多是textXML,所以那时多用responseTextresponseXML来获取结果
    现在服务器返回多为json数据

    http的状态码

    除了请求有状态码之外,响应也有对应的状态码
    我们可以通过statusstatusText来获取

    const status = XHR.response.status;
    const statusText = XHR.response.statusText;
    
    • 1
    • 2

    具体关于HTTP响应码相关的内容可以看我这篇文章
    前端网络基础

    超时时间

    为了避免过长的网络请求时间而服务器迟迟无法返回数据的情况,我们可以设置一个超时时间
    当达到设置的时间后如果还没能拿到数据则会自动取消这个请求
    默认值为0,表示没有设置超时时间
    timeout的单位为毫秒

    XHR.timeout = 10*1000
    
    • 1

    封装自己AJAX函数

    function AJAX({
        method,
        url,
        asy = true,
        timeout = 0,
        data = {},
        success,
        failure
    }) {
        const xhr = new XMLHttpRequest();
        xhr.responseType = "json"
        xhr.timeout = timeout
        xhr.onload = function () {
            if (xhr.status == 200) {
                success(xhr.response)
            } else {
                failure(xhr.status, xhr.statusText)
            }
        }
        if (method || url || success || failure) {
            throw new Error("未传入指定参数")
            return;
        } else if (method.toLowerCase() == "get") {
            let query = []
            for (const key in data) {
                query.push(`${key}=${data[key]}`)
            }
            url = url + "?" + query.join("&")
            xhr.open(method, url, asy)
            xhr.send()
        } else if (method.toLowerCase() == "post") {
            xhr.open(method, url, asy)
            xhr.setRequestHeader("Content-type", "application/json")
            xhr.send(JSON.stringify(data))
        } else {
            throw new Error("不支持这种方法")
        }
        return xhr;
    }
    
    const xhr = AJAX({
        method: "get",
        url: "http://localhost:8088/get",
        data: {
            name: "zhangsan"
        },
        success: function (res) {
            console.log(res)
        },
        failure: function (status, statusText) {
            console.log(status, statusText)
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    Axios

    Axios是一个基于promise的网络请求库
    它不仅可以在浏览器里发送网络请求,还可以在node.js中发送请求
    它还支持Promise
    请求/响应拦截器等等

    创建Axios请求实例

    当我们从Axios中导入对象时使用的实例为默认实例
    有时候默认实例的配置并不是我们所需的
    所以我们可以创建一个新的实例并传入属于该实例的配置

    const ajax = axios.create({
    	baseURL:"http://localhost:8088"	
    })
    
    • 1
    • 2
    • 3

    通过我们创建的这个实例来发送请求

    ajax.get("/get",{
    	params:{
    	}
    }).then(res=>{
    	console.log(res)
    })
    
    ajax.post("/post",{
    	name:"zhangsan",
    	age:19
    	}
    }).then(res=>{
    	console.log(res)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    请求和响应拦截器

    Axios也可以设置拦截器,拦截每次请求和响应
    请求拦截

    axios.interceptors.request.use(function (config) {
    	console.log("请求成功拦截")
        return config;
      }, function (error) {
      	console.log("请求失败拦截")
        return error;
      });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    响应拦截

    axios.interceptors.response.use(function (response) {
    	console.log("响应成功拦截")
        return response;
      }, function (error) {
      	console.log("响应失败拦截")
        return error;
      });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Fetch

    Fetch是一种更加现代的网络请求方案
    它是早期XMLHTTPRequest的替代方案
    同样也是AJAX的另一种实现方式

    Fetch与XHR的区别

    XHR不同的是

    1. Fetch返回值是一个Promise
    2. Fetch不像XHR一样所有操作都在一个对象上
    3. XHR在上传文件时可以监控进度,Fetch不行

    Fetch数据的响应

    Fetch将数据的响应分成了两个阶段
    服务器返回了数据时为第一个阶段

    1. 在这个阶段我们可以通过检查http响应头来判断请求是否成功
    2. 如果因为网络问题,url不正确等导致Fetch无法建立http请求,那么Promise就会reject
    3. http响应码404,500异常状态码时将不会导致error
    4. 我们可以通过response.status来获得http状态码

    第二个阶段为我们通过其他方法获取数据

    1. response.text()
      文本的形式返回
    2. response.json()
      json的形式返回

    发送Fetch请求

    发送get请求

    async function getData() {
    	const response = await fetch("http://localhost:8088/get")
    	const data = await response.json()
    	console.log(data)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    发送post请求

    const params = {
    	name:"zhangsan",
    	age:18
    }
    async function getData() {
    	const response = await fetch("http://localhost:8088/get",{
    		method:"post",
    		headers:{
    			"Content-type", "application/json; charset=utf-8"
    		},
    		body:JSON.stringify(params)
    	})
    	const data = await response.json()
    	console.log(data)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    封装Axios

    我们可以基于Axios简易封装一个自己的网络请求库

    async function httpGet(url, params) {
    	const request = await axios.get(url, {
    		params
    	})
    	return request
    }
    async function httpPost(url, data) {
    	const request = await axios.post(url, data)
    	return request
    }
    
    axios.interceptors.request.use(function(config) {
    	return config;
    }, function(error) {
    	return Promise.reject(error);
    });
    
    axios.interceptors.response.use(function(response) {
    	return response;
    }, function(error) {
    	return Promise.reject(error);
    });
    
    export {
    	httpGet,
    	httpPost
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
  • 相关阅读:
    血泪史!外包如何找到靠谱的兼职程序员?
    win10 火绒 每次打开word、excel都会提示,你要如何打开这个文件
    C语言结构体小栗子
    Nginx 反向代理 SSL 证书绑定域名
    js数组中的map方法
    Django框架基础
    HarmonyOS开发(四):UIAbility组件
    webpack配置完全指南
    Windows11怎么直接显示更多选项?
    反射和工厂设计模式(JAVA基础九)
  • 原文地址:https://blog.csdn.net/qq_46244470/article/details/133136406