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>
出于安全性考虑, 浏览器默认禁止了file协议这种用法,会被浏览器认为是跨域访问,所以会报被跨域资源共享的安全策略等错误。
如果存在跨域等问题代码,不要直接本地打开html,丢服务器环境中测试就行了。
集成环境也有很多软件,如PHPstudy2018版 ,WampServer,APMServ,这类集成环境解压即可用。
截图
Takitooru 发表于 2022-10-21 12:41
出于安全性考虑, 浏览器默认禁止了file协议这种用法,会被浏览器认为是跨域访问,所以会报被跨域资源共享 ...
你好,你说的情况我知道。所以我才需要捕获请求错误,让用户选择文件。
实际场景是这样的,我开发了一个web小应用,当部署到云端时,会直接读取根目录数据。
但也可以本地运行,如果是本地运行,则捕获请求错误后,由用户选择本地文件来读取。
所以,我现在的问题是无法捕获请求错误,请大佬指教,感谢。 promise 无法通过trycatch 方式捕获错误,你需要改成async await方式,然后try catch 才能捕获到错误。 用传统的回调函数,不用用es6的promise,promise 用reject
https://www.cnblogs.com/homeStrong/p/8231889.html ajax 请求是异步的, 直接这样应该不行
在这里看看能不能检测到请求失败
xhr.onreadystatechange=function (){
}
不是这么写的 本帖最后由 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>
XMLHttpRequest的事件除了你用到的load(请求完成成功后后),还有error(错误时获取,例如跨域问题),timeout(超时),abort(主动取消),progress(上传进度),loadend(无论成功/失败,统一处理).在里这需求里可以使用error lucklys 发表于 2022-10-21 14:09
这样写应该满足你的需求了
页:
[1]
2