JavaScript调用REST接口无法获取正常XML响应,浏览器显示正常
解决XMLHttpRequest获取异常响应的问题
嘿,我来帮你搞定这个问题~ 你遇到的情况大概率是因为服务器返回的内容经过了压缩处理(比如gzip),而你的同步XMLHttpRequest请求没有正确处理压缩,导致拿到的是压缩后的乱码内容;而浏览器直接打开URL时,会自动帮你解压内容,所以短暂显示异常后能正常展示XML。另外,你用的同步请求也有不少坑,咱们一步步来调整:
1. 优先换成异步请求(同步请求的坑太多)
同步请求会阻塞页面主线程,现代浏览器甚至会在某些场景下禁止它,所以先改成异步模式,用onload事件处理响应:
var request = new XMLHttpRequest(); // 第三个参数设为true,开启异步 request.open("GET", "https://findtest.akamai.com/_api/search/query?querytext=%27Agora%27&sourceid=%2782cdf98b-cc8b-48c3-a706-d88c1333cc4b%27&QueryTemplatePropertiesUrl=%27spfile://webroot/queryparametertemplate.xml%27&rowlimit=60&selectproperties=%27Title,Author,Url,Date%27&StartRow=%270%27&trimduplicates=%27true%27", true); // 告诉服务器你支持压缩格式,让它返回合适的内容 request.setRequestHeader('Accept-Encoding', 'gzip, deflate'); request.onload = function() { // 先检查请求是否成功 if (request.status >= 200 && request.status < 400) { // 优先用responseXML获取解析好的XML对象,这比responseText更靠谱 var xmlDoc = request.responseXML; if (xmlDoc) { // 把XML对象转成字符串展示 var xmlSerializer = new XMLSerializer(); var xmlString = xmlSerializer.serializeToString(xmlDoc); // 别用document.write,它会覆盖页面,换成插入到DOM里 document.body.appendChild(document.createTextNode(xmlString)); } else { // 如果responseXML为空,尝试手动解码响应内容 var decoder = new TextDecoder('utf-8'); var decodedText = decoder.decode(request.response); document.body.appendChild(document.createTextNode(decodedText)); } } else { console.error('请求出错啦,状态码:', request.status); } }; // 处理请求失败的情况 request.onerror = function() { console.error('请求连接失败,请检查网络或URL'); }; request.send();
2. 为什么直接打开URL能正常显示?
浏览器在加载URL时,会自动识别响应的Content-Encoding头(比如gzip),然后自动解压内容,再渲染成XML;而你的原始同步请求可能没有正确触发浏览器的自动解压逻辑,或者因为同步模式的限制,导致拿到的是未解压的原始二进制内容,转成字符串后就变成了“异常内容”。
3. 额外提醒
- 别再用
document.write了,它在页面加载完成后会覆盖整个页面,用DOM插入的方式更安全。 - 如果服务器返回的XML编码不是UTF-8,你需要调整
TextDecoder的参数(比如'utf-16'),不过大部分REST服务都会用UTF-8。 - 如果你后续需要处理XML内容,直接用
responseXML返回的Document对象就可以,不用转成字符串,方便用DOM API操作。
内容的提问来源于stack exchange,提问作者Prateek Bhuwania
相关产品推荐
相关产品推荐

