cqwcns 发表于 2022-10-21 12:18

JS,如何try/catch到XMLHttpRequest错误

需求比较简单,就是首先需要XMLHttpRequest请求一个数据。
如果请求成功,则继续执行。
如果请求失败,则等待用户操作上传,直到获得文件再继续。


我使用了async/await+Promise。
但现在的问题就是XMLHttpRequest错误时,无法捕获(即无法转到上传数据代码块)。
(完整测试代码见下文)
不知道应该这么写,请各位大佬指教。感谢。

<!DOCTYPE html>
<html lang="zh-CN">

<head>
<meta charset="utf-8">
<title>TEST</title>
<!-- Vue 3 -->
<script src="https://candyissupersweet.gitee.io/cdn/vue3/vue.global.prod.js"></script>
</head>

<body>

<div id="app"> </div>

<script type="text/javascript">
    let that = null, App = null;

    App = {
      mounted() {
      that = this;
      that.start();
      },
      methods: {
      async start() {
          const myData = await that.getData();
          console.log('开始使用数据');
          console.log('myData', myData);
      },
      getData() {
          return new Promise((res, rej) => {

            try {
            const xhr = new XMLHttpRequest();
            xhr.open('get', '/data.txt', true);
            xhr.onload = () => {
                res(handleData(xhr.response))
            };
            xhr.send();
            } catch (error) {
            // 【备用数据步骤】
            // 当出现跨域请求等错误导致无法获得数据时,用备用数据。
            // 这里一些逻辑生成data
            // 用户上传打开文件
            const data = [];
            res(handleData(data))
            }

            // 处理数据
            function handleData(data) {
            // 加工一下数据
            return data
            }
          })
      }
      }
    }

    const app = Vue.createApp(App);
    app.mount("#app");

</script>
</body>

</html>

Takitooru 发表于 2022-10-21 12:41

出于安全性考虑, 浏览器默认禁止了file协议这种用法,会被浏览器认为是跨域访问,所以会报被跨域资源共享的安全策略等错误。

如果存在跨域等问题代码,不要直接本地打开html,丢服务器环境中测试就行了。

集成环境也有很多软件,如PHPstudy2018版   ,WampServer,APMServ,这类集成环境解压即可用。

截图

cqwcns 发表于 2022-10-21 13:04

Takitooru 发表于 2022-10-21 12:41
出于安全性考虑, 浏览器默认禁止了file协议这种用法,会被浏览器认为是跨域访问,所以会报被跨域资源共享 ...

你好,你说的情况我知道。所以我才需要捕获请求错误,让用户选择文件。

实际场景是这样的,我开发了一个web小应用,当部署到云端时,会直接读取根目录数据。

但也可以本地运行,如果是本地运行,则捕获请求错误后,由用户选择本地文件来读取。

所以,我现在的问题是无法捕获请求错误,请大佬指教,感谢。

xmiter 发表于 2022-10-21 13:15

promise 无法通过trycatch 方式捕获错误,你需要改成async await方式,然后try catch 才能捕获到错误。

zpy2 发表于 2022-10-21 13:24

用传统的回调函数,不用用es6的promise,promise 用reject
https://www.cnblogs.com/homeStrong/p/8231889.html

Vvvvvoid 发表于 2022-10-21 13:25

ajax 请求是异步的, 直接这样应该不行
在这里看看能不能检测到请求失败
xhr.onreadystatechange=function (){
               
            }

lucklys 发表于 2022-10-21 13:44

不是这么写的

lucklys 发表于 2022-10-21 14:09

本帖最后由 lucklys 于 2022-10-21 14:49 编辑

<!DOCTYPE html>
<html lang="zh-CN">
        <head>
                <meta charset="utf-8" />
                <title>TEST</title>
                <!-- Vue 3 -->
                <script src="https://candyissupersweet.gitee.io/cdn/vue3/vue.global.prod.js"></script>
        </head>

        <body>
                <div id="app"></div>

                <script type="text/javascript">
                        let that = null,
                                App = null

                        App = {
                                mounted() {
                                        that = this
                                        that.start()
                                },
                                methods: {
                                        async start() {
                                                try {
                                                        const myData = await that.getData()
                                                        console.log(myData)
                                                        if (myData) {
                                                                console.log('开始使用数据')
                                                                console.log('myData', myData)
                                                        }
                                                } catch (error) {
                                                        console.log('捕获错误')
                                                        console.log(error)
                                                        // 【备用数据步骤】
                                                        // 当出现跨域请求等错误导致无法获得数据时,用备用数据。
                                                        // 这里一些逻辑生成data
                                                        // 用户上传打开文件
                                                        const data = []
                                                        this.handleData(data)
                                                }
                                        },
                                        // 处理数据
                                        handleData(data) {
                                                console.log(data)
                                                // 加工一下数据
                                                return data
                                        },
                                        getData() {
                                                let self = this
                                                return new Promise((res, rej) => {
                                                        const xhr = new XMLHttpRequest()
                                                        xhr.open('get', '/data.txt', true)
                                                        xhr.onload = function () {
                                                                if (xhr.status < 400) res(xhr.responseText)
                                                        }
                                                        xhr.onerror = function (e) {
                                                                rej(e)
                                                        }
                                                        xhr.send()
                                                })
                                        },
                                },
                        }

                        const app = Vue.createApp(App)
                        app.mount('#app')
                </script>
        </body>
</html>

lz1987 发表于 2022-10-21 14:38

XMLHttpRequest的事件除了你用到的load(请求完成成功后后),还有error(错误时获取,例如跨域问题),timeout(超时),abort(主动取消),progress(上传进度),loadend(无论成功/失败,统一处理).在里这需求里可以使用error

lucklys 发表于 2022-10-21 14:51

lucklys 发表于 2022-10-21 14:09


       


这样写应该满足你的需求了
页: [1] 2
查看完整版本: JS,如何try/catch到XMLHttpRequest错误