云迈博客

您现在的位置是:首页 > 前端技术 > 原生js相关 > 正文

原生js相关

原生js异步请求

dengkai2022-05-31原生js相关241
˃XMLHttpRequest是一个浏览器接口,开发者可以使用它提出HTTP和HTTPS请求,而且不用刷新页面就可以修改页面内容。一、创建XMLHttpRequest对象IE6及以下版本let

XMLHttpRequest是一个浏览器接口,开发者可以使用它提出HTTP和HTTPS请求,而且不用刷新页面就可以修改页面内容。

一、创建XMLHttpRequest对象

IE6及以下版本

let req = new ActiveXObject("Microsoft.XMLHTTP")

非IE浏览器及IE7及以上版本

let req = new XMLHttpRequest()

二、发送异步请求

1. 打开连接,初始化HTTP请求的参数

open(method, url, async, username, password)

参数说明:

method:用于请求的HTTP方法,包括GET、POST和HEAD
url: 所调用的服务器资源的url
async:是否是异步请求,默认true
username:授权用户名,可选参数
password:认证密码,可选参数

2. 设置请求头

setRequestHeader(字段名, 值)

例如:

req.setRequestHeader("Content-Type", "application/json")

3. 发送请求

send(请求参数)

4. 请求状态

XMLHttpRequest对象把一个Http请求发送到服务器时将经历若干状态,ReadyState属性表示请求的状态。取值及说明如下:

说明
0 已创建XMLHttpRequest对象,但还没有初始化,及还未调用open方法
1 正在加载:open方法已调用
2 请求已发送:已调用send方法,但服务器还未响应
3 请求处理中:已接收到HTTP响应头信息,但消息体还未完全接收结束
4 请求已完成:数据接收完毕,服务器的响应完成

5. 接收服务器响应数据

当ReadyState发生改变的时候,XMLHttpRequest对象会触发onreadystatechange事件。
在响应处理函数中通常会根据XMLHttpRequest对象的ReadyState和其他属性决定如何处理

XMLHttpRequest对象常用属性
属性 | 说明
——– | —–
responseText | 文本响应内容。ReadyState=0,1,2时,此属性为空字符串。ReadyState=3时,此属性为完成的响应信息。ReadyState=4时,此属性为响应信息
responseXML | 用于当接收到完整的响应时(ReadyState=4时)描述XML响应。0~3时此属性为null
status | HTTP状态码。ReadyState的值为3或4时,此属性才可用
statusText | 描述HTTP状态码文本。ReadyState的值为3或4时,此属性才可用

三、基于Promise封装详细代码

1. request.js文件


export const baseURL = ""

/**
 * 请求头处理函数
*/
export function header(){
    let header = {
        'Content-Type': 'application/x-www-form-urlencoded',
        // 'Content-Type': 'application/json',
        "token": "ABC"
    }
    return header
}

/**
 * 网络请求
 * @param url     请求路径
 * @param data    请求数据
 * @param method  请求方法
 */
 export default function request(url, data, method = "GET") {
    const GET_REQ = method == "GET" || method == "get"
    const POST_REQ = method == "POST" || method == "post"
    const head = header()
    // 将对象key:value形式改为key1=value1&key2=value2形式
    let param = ""
    for(let key in data){
        param += key + "=" + data[key] + "&"
    }
    param = param.endsWith("&") ? param.substr(0, param.length - 1) : param
    // 如果是get请求方式,则直接拼接到url中
    url = GET_REQ ? url + "?" + param : url

    return new Promise((resolve, reject) => {
        let req = window.XMLHttpRequest ? new XMLHttpRequest() : window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : null
        if(!req) throw new Error("无法创建请求")

        req.open(method, baseURL + url)
        // 设置请求头
        for(let key in head){
            req.setRequestHeader(key, head[key])
        }
        if(GET_REQ){ 
            req.send()
        }
        else if(POST_REQ){ 
            if(head['Content-Type'] == "application/x-www-form-urlencoded"){
                req.send(param)
            }else if(head['Content-Type'] == "application/json"){
                req.send(JSON.stringify(data)) 
            }
        }
        // 响应处理
        req.onreadystatechange = function (e) {
            // console.log("请求状态改变", e)
            if (req.readyState == 4) {
                if (req.status == 200) {
                    // console.log(req.responseText, typeof req.responseText)
                    let res = JSON.parse(req.responseText)
                    // 根据自定义请求码判定是否成功
                    if(res.code == 1){
                        resolve(res)
                    }else{
                        reject(res)
                    }
                }
                //其他状态码处理 
                else{
                    console.log("请求出错", req.status, req.responseText)
                    reject(req.status, req.responseText)
                }
            }
        }
    })
}

/**
 * 上传文件
 * @param { Object } file 文件对象
 * @param { Function } progressHandler 监听上传进度
 * @param { Function } successHandler 上传成功回调
 */
export function upload(file,progressHandler,successHandler){
    let formData = new FormData();
    formData.append("file", file);

    let req = window.XMLHttpRequest ? new XMLHttpRequest() : window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : null
    if(!req) throw new Error("无法创建请求")

    req.onreadystatechange = function() {
        if (req.readyState === 4 && req.status === 200) {
            console.log("上传成功", req.responseText);
            if(successHandler){
                successHandler(JSON.parse(req.responseText))
            }
        }
    };

    req.upload.addEventListener("progress", function(event) {
        if(event.lengthComputable){
            let percent = Math.ceil(event.loaded * 100 / event.total);
            console.log("上传进度", percent)
            if(progressHandler){
                progressHandler(percent)
            }
        }
    }, false);

    req.open("POST", baseURL + "/common/upload");
    req.send(formData);
}

2. api.js:接口地址

import request from "./request.js"

export const UserInfo = (data) => request("./data/user.json", data)
export const OrderInfo = (data) => request("./data/order.json", data)

这里模拟一下服务器返回的数据:
/data/user.json文件

{
    "code": 1,
    "msg": "获取用户信息成功",
    "data": {
        "id": 1,
        "name": "dk",
        "gender": "男"
    }
}

/data/order.json文件

{
    "code": 1,
    "msg": "获取订单信息成功",
    "data": {
        "id": 1,
        "number": "DJKFDSJ001",
        "name": "零食"
    }
}

3. 执行异步请求

在html文件中调用(需要在服务器环境下运行)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原生js异步请求</title>
</head>
<body>
    <script type="module">
        import { UserInfo, OrderInfo } from "./api.js"

        UserInfo({
            id: "1",
            name: "DK"
        }).then(({ data })=>{
            console.log("用户信息", data)
        })
        const { data } = await OrderInfo({ id: 1 })
        console.log("订单信息", data)
    </script>

    <!-- 上传文件 -->
    <input type="file"/>
    <script type="module">
        import { upload } from "./request.js"

        let fileSelector = document.querySelector("input")
        fileSelector.onchange = function(){
            upload(this.files[0])
        }
    </script>
</body>
</html>

发表评论

评论列表

  • 这篇文章还没有收到评论,赶紧来抢沙发吧~