XMLHttpRequest同步请求报错如何解决?客户端服务端通信有哪些替代方案?
报错原因
你遇到的报错是因为调用xhr.open()时第三个参数传入了false,指定发起同步XMLHttpRequest请求。同步请求会完全阻塞浏览器主线程,请求返回前用户无法和页面做任何交互,严重影响使用体验,因此现代浏览器已经废弃了主线程上的同步XHR用法。
解决方案1:调整XMLHttpRequest为异步模式
将xhr.open的第三个参数改为true(默认值,也可以省略不写)即可切换为异步模式,异步请求的响应结果需要通过回调函数处理,无法直接同步return,调整后代码如下:
tablink = tab.url; $("#p1").text("Selected URL - "+tablink); var xhr=new XMLHttpRequest(); // 对url参数做编码,避免特殊字符导致传参异常 params="url="+encodeURIComponent(tablink); // 第三个参数传true启用异步 xhr.open("POST","http://localhost/WebExt/clientServer.php",true); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // 请求成功回调 xhr.onload = function() { if(xhr.status === 200) { const resp = xhr.responseText; $("#div1").text(resp); // 后续需要处理响应的逻辑都写在这里即可 handleResult(resp); } } // 请求异常回调 xhr.onerror = function() { console.error('请求失败:', xhr.statusText); } xhr.send(params);
解决方案2:使用Fetch API替代(更推荐的现代方案)
Fetch API是浏览器原生提供的新一代异步请求接口,返回Promise对象,配合async/await语法可以写出更简洁易读的代码,完全可以替代XMLHttpRequest完成同等通信需求,等效实现代码如下:
// 封装为async异步函数,可以直接return响应结果 async function requestServer() { const tablink = tab.url; $("#p1").text("Selected URL - "+tablink); try { const resp = await fetch("http://localhost/WebExt/clientServer.php", { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `url=${encodeURIComponent(tablink)}` }); const result = await resp.text(); $("#div1").text(result); return result; } catch (err) { console.error('请求出错:', err); } } // 调用方式示例 requestServer().then(result => { // 在这里处理返回的响应结果 console.log('服务端返回:', result); })
额外安全提示
你当前的PHP代码直接将用户传入的url参数拼接到exec执行的系统命令中,存在严重的命令注入漏洞,建议对$_POST['url']做严格的格式校验,比如仅允许符合规范的HTTP/HTTPS链接传入,避免被攻击者传入恶意命令执行任意操作。
内容的提问来源于stack exchange,提问作者Ajin Mathew
相关产品推荐
相关产品推荐

