When trying to put the image/png response of an xmlHTTPRequest I am getting garbage data

懵懂的女人 提交于 2021-02-08 11:10:11

问题


I am using the below code to call a captcha generating web service. The response is fetched correctly but when trying to append the result under a div the image appears as garbage text

var xmlHttp = new XMLHttpRequest();
          xmlHttp.onreadystatechange = function() { 
              if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
               { 
              window.alert(xmlHttp.getAllResponseHeaders()); 
                 document.getElementById("captchaDiv2").innerHTML = "<img src=\"data:image/png;base64," + xmlHttp.responseText + "\"/>";
               }
          }
          xmlHttp.open("GET", captchaSrc, true); // true for asynchronous 
          xmlHttp.send(null);

The response header is the below, as you can see the type is image/png

Yet when I try to import it inside the html I am getting the below:

Can you please advise what could be the root cause behind this? I already tried btoa() with and without encoding... No results.


回答1:


This answer uses the information from https://stackoverflow.com/a/11562550/266561 - long story short: the string you get in XHR is a bit hard to convert to base64 because the string seems to be converted to UTF-8 and then it seems corrupted, and base64 string is no longer valid. Moreover, if you try to btoa(xmlHttp.responseText) you get error in Chrome because of non-ascii characters..

BUT, there is a solution. First, make an empty <img id="captchaImg" /> element for simplicity of embedding the new src. Then,

var xmlHttp = new XMLHttpRequest();
xmlHttp.responseType = "arraybuffer";
xmlHttp.onreadystatechange = function() { 
  if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { 
    document.getElementById("captchaImg").setAttribute('src', 'data:image/png;base64,' + btoa(String.fromCharCode.apply(null, new Uint8Array(xmlHttp.response))));
  }
}
xmlHttp.open("GET", captchaSrc, true); // true for asynchronous
xmlHttp.send(null);

The trick here is xmlHttp.responseType = "arraybuffer" to ensure our data is kept safe and not garbled. As of compatibility point of view, if I understand correctly from MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays), the support for typed arrays is from IE 10 and is even supported in old Safari 5.1 (which was the last version for Windows).



来源:https://stackoverflow.com/questions/42924898/when-trying-to-put-the-image-png-response-of-an-xmlhttprequest-i-am-getting-garb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!