XMLHttpRequest—>Promise

时间:2024-03-05 07:14:26

XMLHttpRequest.open()

初始化 HTTP 请求参数

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

method 参数是用于请求的 HTTP 方法。值包括 GET、POST 和 HEAD。

( 大小写不敏感。

POST:用"POST"方式发送数据,可以大到4MB

GET:用"GET"方式发送数据,只能256KB
如果请求带有参数的化实用POST方式,POST方式将参数放置在页面的隐藏控件内
没有参数使用GET方式
对于请求的页面在中途可能发生更改的,也最好用POST方式)

url 参数是请求的主体。大多数浏览器实施了一个同源安全策略,并且要求这个 URL 与包含脚本的文本具有相同的主机名和端口。浏览器自己是可以发起跨域请求的(如a标签、img标签、form表单等),但Javascript不能去CORS跨域获取资源(如ajax)

async 一个可选的布尔参数,表示是否异步执行操作,默认为true异步。如果这个参数是 false,请求是同步的,后续对 send() 的调用将阻塞,直到响应完全接收。

如果这个参数是 true 或省略,请求是异步的,且通常需要一个 onreadystatechange 事件句柄。

username 和 password 参数是可选的,为 url 所需的授权提供认证资格。如果指定了,它们会覆盖 url 自己指定的任何资格。

说明

这个方法初始化请求参数以供 send() 方法稍后使用。它把 readyState 设置为1,删除之前指定的所有请求头部,以及之前接收的所有响应头部,

并且把 responseText、responseXML、status 以及statusText 参数设置为它们的默认值。

当 readyState 为 0 的时候(当 XMLHttpRequest 对象刚创建或者abort() 方法调用后)以及当 readyState 为 4时(已经接收响应时),

调用这个方法是安全的。

当针对任何其他状态调用的时候,open() 方法的行为是为指定的。

除了保存供 send() 方法使用的请求参数,以及重置 XMLHttpRequest 对象以便复用,open() 方法没有其他的行为。

要特别注意,当这个方法调用的时候,实现通常不会打开一个到 Web 服务器的网络连接。

XMLHttpRequest异步请求。案例1

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 
 4 <head>
 5     <meta charset="UTF-8">
 6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7     <title>XMLHttpRequest异步请求</title>
 8 
 9     <c>//通过XMLHttpRequest对象,异步请求</c>
10     <!-- 容器 -->
11     <img id="img">
12 
13     <c>//在rep返回之后,再发送req_2请求</c>
14     <!-- 容器2 -->
15     <img id="img_2">
16 </head>
17 
18 <body>
19     <script>
20         //const 声明一个只读的常量,一旦声明,常量的值就不能改变。
21 
22         //创建 XMLHttpRequest对象
23         const rep = new XMLHttpRequest();
24 
25         //https://acg.toubiec.cn/random.php 写真与二次元
26         //API - 樱次元https://www.yingciyuan.cn/
27         //https://acg.toubiec.cn随机二次元图片
28         //https://www.dmoe.cc/随机二次元图片API-樱花
29         //韩小韩API接口站https://api.vvhan.com/api/acgimg一个随机二次元图片接口
30         const url = "https://api.vvhan.com/api/acgimg";
31 
32         // 再次声明-----------------------
33         const url_2 = "https://acg.toubiec.cn/random.php";
34         const rep_2 = new XMLHttpRequest();
35 
36         // 获得dom元素
37         const img_2 = document.querySelector('#img_2');
38         const img = document.querySelector('#img');
39 
40         // 初始rep-----------------------------------------------------------------
41         //以get的方式,向url发送,异步请求
42         rep.open('GET', url);
43 
44         //请求的格式为图片格式
45         rep.responseType = 'blob';
46 
47         //onload监听器,事件在对象被加载后发生
48         rep.onload = function () {
49             //如果请求对象.的状态码为200
50             if (rep.status === 200) {
51                 console.log('rep对象')
52                 //修改img的是src链接
53                 img.src = url;
54 
55                 //在rep返回之后,再次发送req_2请求--------------------------------------
56                 rep_2.send();
57 
58             } else {
59                 //否则返回失败
60                 console.log('失败');
61             }
62         }
63         // onerror监听器,监听链接问题
64         rep.onerror = function () {
65             console.log('network error网络错误');
66         }
67         // rep对象,发送请求
68         rep.send();
69 
70 
71         // 初始化,rep_2 -----------------------------------------------------------------
72         //以get的方式,向url发送请求
73         rep_2.open('GET', url);
74 
75         //请求的格式为图片格式
76         rep_2.responseType = 'blob';
77 
78         //onload页面渲染成功返回一个回调函数
79         rep_2.onload = function () {
80             //如果请求对象.的状态码为200
81             if (rep_2.status === 200) {
82                 console.log('rep_2对象')
83                 //修改img的是src链接
84                 img_2.src = url_2;
85             } else {
86                 //否则返回失败
87                 console.log('失败');
88             }
89         }
90         // onerror监听器,监听链接问题
91         rep_2.onerror = function () {
92             console.log('network error网络错误');
93         }
94     </script>
95 </body>
96 
97 </html>

 Promise封装函数。案例2

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7     <title>Promise</title>
  8 
  9     <c>//通过Promise封装函数,发送异步请求</c>
 10     <!-- 容器 -->
 11     <img id="img">
 12 
 13     <c>//通过Promise封装函数,再次发送请求req_2</c>
 14     <!-- 容器2 -->
 15     <img id="img_2">
 16 
 17 </head>
 18 
 19 <body>
 20     <script>
 21         //const 声明一个只读的常量,一旦声明,常量的值就不能改变。
 22         //https://acg.toubiec.cn/random.php 写真与二次元
 23         //API - 樱次元https://www.yingciyuan.cn/
 24         //https://acg.toubiec.cn随机二次元图片
 25         //https://www.dmoe.cc/随机二次元图片API-樱花
 26         //韩小韩API接口站https://api.vvhan.com/api/acgimg一个随机二次元图片接口
 27         const url = "https://api.vvhan.com/api/acgimg";
 28         const url_2 = "https://cdn.jsdelivr.net/gh/uxiaohan/GitImgTypecho/Acg/api.vvhan.com[217].jpg"
 29 
 30         // 获得dom元素
 31         const img = document.querySelector('#img');
 32         const img_2 = document.querySelector('#img_2');
 33 
 34         //封装一个功能函数,参数传入。
 35         function p(img, url) {
 36 
 37             /*  
 38             Prminse在声明时候就被运行了。接受一个回调函数,有两个参数resolve, reject
 39             Prminse作用把内部的 异步操作代码 包装起来。留出新的接口 方式通过resolve, reject。
 40 
 41             流程原理:
 42                 等待Prminse内部的异步代码运行完成,触发事情,获得回调函数之后,返回resolve, reject。
 43                 resolve结果传入then(返回一个回调函数) 
 44                 reject结果传入catch(返回一个回调函数) 
 45             */
 46             new Promise((resolve, reject) => {
 47 
 48                     //创建 XMLHttpRequest对象
 49                     const rep = new XMLHttpRequest();
 50 
 51                     //以get的方式,向url发送,异步请求
 52                     rep.open('GET', url);
 53 
 54                     //请求的格式为图片格式
 55                     rep.responseType = 'blob'; // then()会返回一个 Blob对象
 56 
 57                     //onload监听器,事件在对象被加载后发生
 58                     rep.onload = function () {
 59                         //如果请求对象.的状态码为200
 60                         if (rep.status === 200) {
 61                             //修改img的是src链接
 62                             img.src = url;
 63 
 64                             console.log('//返回rep响应的结果')
 65                             return resolve(rep.response);
 66                         } else {
 67                             //否则返回失败
 68                             console.log('失败');
 69                             //返回 失败结果
 70                             return reject(Error('failed失败'))
 71 
 72                         }
 73                     }
 74 
 75                     // onerror监听器,监听链接问题
 76                     rep.onerror = function () {
 77                         console.log('network error网络错误');
 78 
 79                         //依然返回错误 
 80                         return reject(Error('network error网络错误'))
 81                     }
 82                     // rep对象,发送请求
 83                     rep.send();
 84 
 85                 })
 86                 .then((res) => {
 87                     console.log(res)
 88                 })
 89                 .catch((err) => {
 90                     console.log(err)
 91                 });
 92         }
 93 
 94         // 函数的调用
 95         // 获得一张图片
 96         p(img, url);
 97         // 再次获得一张图片
 98         p(img_2, url_2);
 99     </script>
100 
101 </body>
102 
103 </html>

 分析Promise如何then()衔接。案例3

  1 <!-- 
  2 分析Promise如何then()衔接
  3 -->
  4 <!DOCTYPE html>
  5 <html lang="en">
  6 
  7 <head>
  8     <meta charset="UTF-8">
  9     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 10     <title>分析Promise如何then()衔接</title>
 11 
 12     <c>//通过Promise封装函数,发送异步请求</c>
 13     <!-- 容器 -->
 14     <img id="img">
 15 
 16     <c>//通过Promise封装函数,再次发送请求req_2</c>
 17     <!-- 容器2 -->
 18     <img id="img_2">
 19 
 20 </head>
 21 
 22 <body>
 23     <script>
 24         //const 声明一个只读的常量,一旦声明,常量的值就不能改变。
 25         //https://acg.toubiec.cn/random.php 写真与二次元
 26         //API - 樱次元https://www.yingciyuan.cn/
 27         //https://acg.toubiec.cn随机二次元图片
 28         //https://www.dmoe.cc/随机二次元图片API-樱花
 29         //韩小韩API接口站https://api.vvhan.com/api/acgimg一个随机二次元图片接口
 30         const url = "https://api.vvhan.com/api/acgimg";
 31         const url_2 = "https://cdn.jsdelivr.net/gh/uxiaohan/GitImgTypecho/Acg/api.vvhan.com[217].jpg"
 32 
 33         // 获得dom元素
 34         const img = document.querySelector('#img');
 35         const img_2 = document.querySelector('#img_2');
 36 
 37 
 38 
 39         //封装一个功能函数,参数传入。
 40         function p(img, url) {
 41 
 42             /*  
 43             Prminse在声明时候就被运行了。接受一个回调函数,有两个参数resolve, reject
 44             Prminse作用把内部的 异步操作代码 包装起来。留出新的接口 方式通过resolve, reject。
 45 
 46             流程原理:
 47                 等待Prminse内部的异步代码运行完成,触发事情,获得回调函数之后,返回resolve, reject。
 48                 resolve结果传入then(返回一个回调函数) 
 49                 reject结果传入catch(返回一个回调函数) 
 50             */
 51             new Promise((resolve, reject) => {
 52 
 53                 //创建 XMLHttpRequest对象
 54                 const rep = new XMLHttpRequest();
 55 
 56                 //以get的方式,向url发送,异步请求
 57                 rep.open('GET', url);
 58 
 59                 //请求的格式为图片格式
 60                 rep.responseType = 'blob'; // then()会返回一个 Blob对象
 61 
 62                 //onload监听器,事件在对象被加载后发生
 63                 rep.onload = function () {
 64                     //如果请求对象.的状态码为200
 65                     if (rep.status === 200) {
 66                         //修改img的是src链接
 67                         img.src = url;
 68 
 69                         console.log('//返回rep响应的结果')
 70                         return resolve(rep.response);
 71                     } else {
 72                         //否则返回失败
 73                         console.log('失败');
 74                         //返回 失败结果
 75                         return reject(Error('failed失败'))
 76 
 77                     }
 78                 }
 79 
 80                 // onerror监听器,监听链接问题
 81                 rep.onerror = function () {
 82                     console.log('network error网络错误');
 83 
 84                     //依然返回错误 
 85                     return reject(Error('network error网络错误'))
 86                 }
 87                 // rep对象,发送请求
 88                 rep.send();
 89             })
 90         }
 91 
 92         // 函数的调用
 93         // 获得一张图片
 94         p(img, url).then(); // 错误:因为 function p 不返回then()内容 
 95         // 再次获得一张图片
 96         p(img_2, url_2);
 97     </script>
 98 
 99 </body>
100 
101 </html>

 在第一个rep返回response响应之后,在运行第二个异步请求。案例4

<!-- 
在第一个rep返回response响应之后,在运行第二个异步请求
-->

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>在第一个rep返回response响应之后,在运行第二个异步请求</title>

    <c>//通过Promise封装函数,发送异步请求</c>
    <!-- 容器 -->
    <img id="img">

    <i>//通过Promise封装函数,再次发送请求req_2</i>
    <!-- 容器2 -->
    <img id="img_2">

</head>

<body>
    <script>
        //const 声明一个只读的常量,一旦声明,常量的值就不能改变。
        //https://acg.toubiec.cn/random.php 写真与二次元
        //API - 樱次元https://www.yingciyuan.cn/
        //https://acg.toubiec.cn随机二次元图片
        //https://www.dmoe.cc/随机二次元图片API-樱花
        //韩小韩API接口站https://api.vvhan.com/api/acgimg一个随机二次元图片接口
        const url = "https://api.vvhan.com/api/acgimg";
        const url_2 = "https://cdn.jsdelivr.net/gh/uxiaohan/GitImgTypecho/Acg/api.vvhan.com[217].jpg"

        // 获得dom元素
        const img = document.querySelector('#img');
        const img_2 = document.querySelector('#img_2');



        //封装一个功能函数,参数传入。
        function p(img, url) {

            /*  
            Prminse在声明时候就被运行了。接受一个回调函数,有两个参数resolve, reject
            Prminse作用把内部的 异步操作代码 包装起来。留出新的接口 方式通过resolve, reject。

            流程原理:
                等待Prminse内部的异步代码运行完成,触发事情,获得回调函数之后,返回resolve, reject。
                resolve结果传入then(返回一个回调函数) 
                reject结果传入catch(返回一个回调函数) 
            */

            //解决方法:直接返回Promise
            return new Promise((resolve, reject) => {

                //创建 XMLHttpRequest对象
                const rep = new XMLHttpRequest();

                //以get的方式,向url发送,异步请求
                rep.open('GET', url);

                //请求的格式为图片格式
                rep.responseType = 'blob'; // then()会返回一个 Blob对象

                //onload监听器,事件在对象被加载后发生
                rep.onload = function () {
                    //如果请求对象.的状态码为200
                    if (rep.status === 200) {
                        //修改img的是src链接
                        img.src = url;

                        console.log('//返回rep响应的结果')
                        return resolve(rep.response);
                    } else {
                        //否则返回失败
                        console.log('失败');
                        //返回 失败结果
                        return reject(Error('failed失败'))

                    }
                }

                // onerror监听器,监听链接问题
                rep.onerror = function () {
                    console.log('network error网络错误');

                    //依然返回错误 
                    return reject(Error('network error网络错误'))
                }
                // rep对象,发送请求
                rep.send();
            })
        }

        // 函数的调用
        // 获得一张图片
        // 因为 then() 是Promise类型带有功能
        p(img, url).then((res) => {

            // 在第一个Promise的resolve之后,才运行第二个 Promise。这时两个Promise就链接在一起了
            p(img_2, url_2);

            console.log(res)
        });
    </script>

</body>

</html>

 Promise如何使用then衔接。案例5

<!-- 
Promise如何使用then衔接
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise如何使用then衔接</title>

    <c>//通过Promise封装函数,发送异步请求</c>
    <!-- 容器 -->
    <img id="img">

    <i>//通过Promise封装函数,再次发送请求req_2</i>
    <!-- 容器2 -->
    <img id="img_2">

</head>

<body>
    <script>
        //const 声明一个只读的常量,一旦声明,常量的值就不能改变。
        //https://acg.toubiec.cn/random.php 写真与二次元
        //API - 樱次元https://www.yingciyuan.cn/
        //https://acg.toubiec.cn随机二次元图片
        //https://www.dmoe.cc/随机二次元图片API-樱花
        //韩小韩API接口站https://api.vvhan.com/api/acgimg一个随机二次元图片接口
        const url = "https://api.vvhan.com/api/acgimg";
        const url_2 = "https://cdn.jsdelivr.net/gh/uxiaohan/GitImgTypecho/Acg/api.vvhan.com[217].jpg"

        // 获得dom元素
        const img = document.querySelector('#img');
        const img_2 = document.querySelector('#img_2');



        //封装一个功能函数,参数传入。
        function p(img, url, count) {

            /*  
            Prminse在声明时候就被运行了。接受一个回调函数,有两个参数resolve, reject
            Prminse作用把内部的 异步操作代码 包装起来。留出新的接口 方式通过resolve, reject。

            流程原理:
                等待Prminse内部的异步代码运行完成,触发事情,获得回调函数之后,返回resolve, reject。
                resolve结果传入then(返回一个回调函数) 
                reject结果传入catch(返回一个回调函数) 
            */

            //解决方法:直接返回Promise
            return new Promise((resolve, reject) => {

                //创建 XMLHttpRequest对象
                const rep = new XMLHttpRequest();

                //以get的方式,向url发送,异步请求
                rep.open('GET', url);

                //请求的格式为图片格式
                rep.responseType = 'blob'; // then()会返回一个 Blob对象

                //onload监听器,事件在对象被加载后发生
                rep.onload = function () {
                    //如果请求对象.的状态码为200
                    if (rep.status === 200) {
                        //修改img的是src链接
                        img.src = url;

                        console.log('//返回rep响应的结果')
                        //return resolve(rep.response);
                        return resolve(count);
                    } else {
                        //否则返回失败
                        console.log('失败');
                        //返回 失败结果
                        return reject(Error('failed失败'))

                    }
                }

                // onerror监听器,监听链接问题
                rep.onerror = function () {
                    console.log('network error网络错误');

                    //依然返回错误 
                    return reject(Error('network error网络错误'))
                }
                // rep对象,发送请求
                rep.send();
            })
        }

        // 函数的调用
        // 获得一张图片
        // 因为 then() 是Promise类型带有功能
        p(img, url, 1)
            .then((res) => {
                console.log(res); //1
                //二次调用Promise
                return p(img_2, url_2, 2); //在这个函数调用时,依然返回Promise
            })
            .then((res) => { //这个then返回结果,是 p(img_2, url_2, 1)的Promise返回resolve的结果
                console.log(res); //2 返回上一步count的结果
                //return p(img_3, url_3, 3);
            })
            //...多个then
            .catch((err) => { //接受,整个链式反应,任何地方发生的错误
                console.log(err);
            });


        /*
        ...
        //多个then链接,某一需要上步结果时候,以参数传递
        .then((res) => { 
            console.log(res); //2 返回上一步count的结果
            return p(img_3, url_3, 3);
        })
        .then((res) => { 
            console.log(res);//3 返回上一步count的结果
            return p(img_4, url_4, 4);
        })
        .then((res) => {
            console.log(res);
            return p(img_5, url_5, 5);
        })
        .then((res) => { 
            console.log(res); 
            return p(img_6, url_6, 6);
        })
        .catch((err) => { //接受,整个链式反应,任何地方发生的错误
             console.log(err);
        });

        */
    </script>

</body>

</html>