Worker中XMLHttpRequest send返回null,onload却能获取数据的问题求助
问题分析与解决办法
嘿,这个问题我之前也踩过坑,其实是同步XMLHttpRequest的特性导致的,咱们一步步拆解:
为什么send()返回null?
首先明确:同步模式下(open的第三个参数传false),send()方法本身不会返回响应内容,它的作用是阻塞主线程,直到请求完成或失败,规范里就定义它的返回值是null——这不是你的代码写错了,是它本来就这么设计的。
而你能在onload里拿到内容,是因为即使是同步请求,onload事件依然会触发,但这里有个更大的问题:你在onload回调里return的内容,根本不会被pegarDados函数捕获到,因为回调函数的执行上下文和外部函数是分开的。
修正方案
方案1:如果一定要用同步请求(不推荐)
直接在send()之后,通过XHR对象的responseText获取内容,不用依赖onload:
function pegarDados(){ let requisicao = new XMLHttpRequest(); requisicao.overrideMimeType('text/plain'); requisicao.setRequestHeader('X-Requested-With', 'JSONHttpRequest'); requisicao.open('GET','./assets/data/dados.json', false); try { requisicao.send(); // 请求成功判断 if (requisicao.status >= 200 && requisicao.status < 300) { return JSON.parse(requisicao.responseText); } else { throw new Error(`请求失败,状态码:${requisicao.status}`); } } catch (err) { console.error('请求或解析出错:', err); return null; } }
⚠️ 注意:同步请求会阻塞主线程,页面在请求完成前会卡死,现代浏览器已经不推荐使用这种方式了。
方案2:推荐的异步请求方式
用Promise封装异步请求,既不会阻塞页面,也能正确获取返回值:
function pegarDados(){ return new Promise((resolve, reject) => { let requisicao = new XMLHttpRequest(); requisicao.overrideMimeType('text/plain'); requisicao.setRequestHeader('X-Requested-With', 'JSONHttpRequest'); requisicao.open('GET','./assets/data/dados.json', true); // 开启异步模式 requisicao.onload = function(){ if (requisicao.status >= 200 && requisicao.status < 300) { try { const dados = JSON.parse(requisicao.responseText); resolve(dados); // 把解析后的数据传递出去 } catch (parseErr) { reject(new Error('JSON解析失败:', parseErr)); } } else { reject(new Error(`请求失败,状态码:${requisicao.status}`)); } }; // 处理网络错误 requisicao.onerror = function() { reject(new Error('网络请求出错,请检查连接或地址')); }; requisicao.send(); }); } // 使用示例 pegarDados() .then(dados => { console.log('获取到的数据:', dados); // 在这里处理数据 }) .catch(erro => { console.error('出错了:', erro); });
关键总结
- 同步XHR的
send()返回null是正常规范行为,不要指望它返回响应内容; - 同步模式下的
onload回调里return没用,因为回调的返回值无法被外部函数捕获; - 优先使用异步请求,避免阻塞页面,提升用户体验。
内容的提问来源于stack exchange,提问作者Henrique Arantes Tiraboschi
相关产品推荐
相关产品推荐

