I have images I need to pull from a server requiring basic authentication. To do that I couldn't just place the URL inside ng-src because I couldn't send an authenticated request, so I manually pull the image data using XHR.
var xhr = new XMLHttpRequest();
xhr.open("GET", 'https://url.com/{id}/picture', true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(userID + ":" + password));
xhr.responseType = 'arraybuffer';
xhr.onload = function(evt) {
if(this.status == 200) {
var uInt8Array = new Uint8Array(this.response);
var i = uInt8Array.length;
var binaryString = new Array(i);
while(i--) {
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var base64 = window.btoa(data);
document.getElementById("test").src="data:"+xhr.getResponseHeader('Content-Type')+";base64,"+base64;
}
};
xhr.send();
Replacing the URL in the code above with the actual path to a picture works and displays the picture inside a div called test
.
Now I need to display a list of these images.
<tr ng-repeat="x in array">
<td">
<div>
<img data-ng-src={{getPictureURL()}} onerror="this.onError=null;this.src='default.png'" >
</div>
</td>
</tr>
Heart of the question:
I put in the first code block into getPictureURL()
, replacing document.getElementById("test").src=
with return
, and it will send a massive number of requests because of ng-repeat and xhr.open opening a connection to the picture URL every iteration on each item in array
. I know that ng-src
won't reload a picture even in ng-repeat
until there is a change in the path to the image. So ultimately, I want to get and return the base64-encoded URL in getPictureURL()
so it can display the pictures.
What should I do?