吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 916|回复: 13
收起左侧

[求助] JS,如何try/catch到XMLHttpRequest错误

[复制链接]
cqwcns 发表于 2022-10-21 12:18
需求比较简单,就是首先需要XMLHttpRequest请求一个数据。
如果请求成功,则继续执行。
如果请求失败,则等待用户操作上传,直到获得文件再继续。


我使用了async/await+Promise。
但现在的问题就是XMLHttpRequest错误时,无法捕获(即无法转到上传数据代码块)。
(完整测试代码见下文)
不知道应该这么写,请各位大佬指教。感谢。
微信图片_20221021121134.png
[HTML] 纯文本查看 复制代码
<!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,这类集成环境解压即可用。

截图

Snipaste_2022-10-21_12-37-26.jpg

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
cqwcns + 1 + 1 谢谢@Thanks!

查看全部评分

 楼主| 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 编辑

[JavaScript] 纯文本查看 复制代码
<!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>

免费评分

参与人数 1吾爱币 +2 热心值 +1 收起 理由
cqwcns + 2 + 1 谢谢@Thanks!

查看全部评分

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
[mw_shl_code=javascript,true]

       

这样写应该满足你的需求了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 06:37

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表