How to use ajax to set the src of an image? - html

I need to set some headers when getting an image. The img src attribute does not allow this, so I'm using an XHR request to get the image. However, when I set the src attribute on the img tag after that request completes, it looks like the request is triggered again. Is there a way to cache the image and not trigger the second request?
Sample Code:
$(document).ready(function() {
var url = 'https://i.imgur.com/bTaDhpy.jpg'
var file = $.get(url);
file.then(function(data) {
$('#foo').attr('src', url);
});
});
JS Fiddle: https://jsfiddle.net/mehulkar/o4Lcs5Lo/
Note: my question is not about how to set the appropriate headers in the xhr request. My question is how to not trigger another GET from the setting of the src attribute and use the response from the XHR to display the image.

Use the $.ajax for this:
var myImg = $('#foo'),
mySrc = 'https://i.imgur.com/bTaDhpy.jpg';
$.ajax({
url: mySrc,
type: "GET",
headers: {
"X-TOKEN": 'xxxxx'
}
}).done(function() {
myImg.attr('src', mySrc); // set the image source
}).fail(function() {
myImg.hide(); // or something other
});

I cannot comment here due to reputation points, but here is what I've found on this.
I have a local html page that I'm executing via file:///
I can use a $.get to dynamically pull svg files into a variable. The debugger shows this as if it were a standard html node <svg. (I'm using Firefox Developer, but also in Firebug I see the svg file as a node.).
So At this point I have an empty <img that I want to set to my svg file I just don't know how to set the src attribute to the actual document itself. I suppose I could encode to base64.. You might be able to set it using the debugger itself. I couldn't get this to work reliably. Another avenue (for me since I'm using svg) is to clone the object then write it node for node. If you're not using svg perhaps there is some similar hack you could conduct with canvas? Load the image as a sprite then read the colors and set pixels?

Related

Display image that returns HTTP 503 in Firefox

I have a status badge image that returns the HTTP code 503 when the respective service is offline (but the webserver is still there serving calls). Now opening the image URL directly will display the image properly, regardless of the underlying 503 error code. But using it inside an <img> tag shows the broken image icon. How can I prevent that while still allowing the image itself to return a 503? (External services depend on that)
Here are some screenshots to illustrate what's going on:
The badge on the page:
The status message in the developer console:
The badge itself:
Note: This happens on Firefox. Not Chrome
Edit: Here are a few requested pieces information:
Firefox 78.0.2 (64-Bit)
It's served from the same domain. But the domain is essentially just proxying serveral underlying webservices. And this badge is originating from a different service but all on the same domain.
It's a SVG image if that makes any difference.
Since XMLHttpRequest can retrieve the output of any request, no matter the response code, it is possible to request for the image with XMLHttpRequest, and then convert the blob response type to a base64 format image, which can be loaded in the browser.
The CORS proxy I used in the sample code may not be necessary in the majority of cases, but could be useful in the case where the image you are trying to display has weird response headers that prevent access to the image from another domain.
Here is the sample code. It should work no matter the response code, CORS, etc.
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var reader = new FileReader();
reader.onloadend = function () {
// here, reader.result contains the base64-formatted string you can use to set the src attribute with
document.getElementsByTagName('img')[0].src = reader.result; // sets the first <img> tag to display the image, change to the element you want to use
};
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', "https://cors-anywhere.herokuapp.com/i.stack.imgur.com/8wB1j.png"); // don't include the HTTP/HTTPS protocol in the url
xhr.responseType = 'blob';
xhr.setRequestHeader('X-Requested-With', 'xhr');
xhr.send();
<img src="about:blank">
Everything works, as when you go into Inspect Element, you see that the src attribute of the <img> tag points to a base64 URL that can load in any browser.
You might want to compress or resize your images before uploading it to server , as they might be large enough to keep the server busy and show the error as most of the time, a 503 error occurs because the server is too busy.
More over the image is SVG so it might render dimesions before completing, hence I'd suggest
Try replacing the SVG with PNG or JPG
Also try for site like https://tinypng.com/ to compress the image size
This might work for you

toDataURL Image download has no extension

I am downloading an image when a div is clicked by using...
document.location.href = save_canvas.toDataURL("image/jpeg").replace("image/jpeg", "image/octet-stream");
This is working but the image that downloads has no extension and is just called 'download'
I have tried setting the name like this...
document.location.download = "myfile.jpg";
document.location.href = save_canvas.toDataURL("image/jpeg").replace("image/jpeg", "image/octet-stream");
But it is having no effect, where am i going wrong?
The download attribute is not part of the Location object as document.location holds, only for the HTML anchor (A) tags (except in IE).
Depending on browser and version you could instead try to convert canvas into a Blob object, then to File in order to set a filename, and serve that as URL via URL.createObjectURL(). Also here, toBlob() is not supported in IE (but you can polyfill toBlob(), and use msSaveBlob instead).
(and you would also want to replace mime-type's "image" with "application" for mime-type (e.g. "application/octet-stream"). )
c.toBlob(function(blob) {
var file = new File([blob], "test.png", {type: "application/octet-stream"});
document.location.href = URL.createObjectURL(file);
})
A save request with PNG and filename should appear when running this code...
<canvas id=c></canvas>
Optionally, try the FileSaver.js library which deals with many special cases.

JQUERY: Dynamically loading and updating iframe content on change() / keyup()

I've been working on a custom CMS in drupal for about two or three weeks now, and I keep running into this same problem. I'm trying to load a dynamically generated url (by extracting the node id of the target drupal page into $resultCut and appending it to the baseurl of the website). This iframe is embedded next to an instance of CKEditor, and the idea is to have the content in the iframe change when the fields in CKEditor are modified. I have the following Jquery:
<script type="text/javascript">
$(document).ready(function(){
baseurl = urlhere;
url = baseurl+"<?php echo $resultCut ?>"
$('#EmuFrame').attr('src', url);
var HTML = $('#EmuFrame').contents().find('body').html();
alert ( "LOADING COMPLETE" + HTML );
});
$('#edit-field-mobile-page-header-label-0-value').change(function () { // writes changes to the header text to emulaor
var curr = $(this).val();
$('#EmuFrame').contents().find("h1").text(curr);
});
$('#edit-body').keyup(function(e) { // writes changes to the body text to emulator
var curr = $(this).val();
currhead = $('#EmuFrame').contents().find("h1").html();
$('#EmuFrame').contents().find('#content').html("<h1>"+currhead+"</h1>"+curr);
});
where #EmuFrame is the id of an iframe, and the #edit-* tags are the ids of fields in CKEditor that I am monitoring for change. When the user types, the keyup() or change() events is supposed to grab the new html and swap it with the html in the iframe.
As of right now, the LOADING COMPLETE alert fires, but there is no html in the alert. I noticed that the content of the iframe loads AFTER the alert fires, however, which is what led me to believe that it's a problem with the order in which the events trigger.
Further, I had an alert in the callback function of keyup that returned the new html [ alert(curr) ] that was generated when a user started typing, and this alert returns html (although, it is being grabbed from CKEditor). However, the iframe does not reflect any changes. If I append [ alert (currhead) ] though, nothing is alerted at all.
It might be of interest to note that the source url is technically on a different domain than the parent. however, I used a workaround (i'm pretty sure it works, because I've previously gotten the whole html replacement thing working, and then somehow it broke). Also, neither Firebug nor Chrome's console report any XMLHttpRequest errors. Also, I keep getting this error: "Uncaught Syntax error, unrecognized expression: [#disabled]" and I'm not sure what it means, and whether its relevant to my problem as stated above.
That was a ridiculously long plea for help, so THANKS FOR READING, and thank you for any help!!
Your note about about the cross-domain iframe src is worrisome -- you shouldn't be able to access its contents with javascript. Nevertheless:
You have these two lines in quick succession:
$('#EmuFrame').attr('src', url);
var HTML = $('#EmuFrame').contents().find('body').html();
Try waiting for the iframe to load first:
$('#EmuFrame').load(function() {
var HTML = $('#EmuFrame').contents().find('body').html();
}

Mootools Request to change javascript code?

So I am planning on dynamically changing a page's content by fetching it from another page.
To do so, I used Mootools' Request class:
var tabContent = new Request({
url: 'foo/bar/baz.php',
onSuccess: function(data) {
$('tab_container').innerHTML = data;
}
}).send();
In any case, the HTML is fetched fine, and returns without a hitch. However, I'd like to add some events to THOSE fetched elements (Fx.slide, to be precise), and that requires some js to be included in the requested file.
Upon inspection of the returned data, the javascript is intact. However, it does not show up in the final product. That is, somewhere in between having received the data, and rendering the data (via the innerHTML bit) it seems as though the javascript has been excised out for some reason.
Hm.
add evalScripts: true to the Request options, then include the script in a simple <script></script> block at the bottom of the response.

dom question: getting the full sourcode from a html document

i'm trying things out with a html document's dom (under visualbasic6) and i was wondering:
how can i get the full html sourcecode including all headers?
is there something like document.all.value?
thanks
If all you have is a DOM, there is no way to retrieve the original source, much less the response headers. It's gone. The DOM is what was generated from the source, which was thrown away thereafter.
If you must have the original source and headers, you will have to fetch it again from the server, using the location object to get the URL. For example from inside a web page script:
var req= 'XMLHttpRequest' in window? new XMLHttpRequest() : new ActiveXObject('MSXML2.XMLHttpRequest');
req.onreadystatechange= function() {
if (this.readyState===4) {
alert('Headers: '+this.getAllResponseHeaders());
alert('Body: '+this.responseText);
}
};
req.open('get', location.href);
req.send(null);
Clearly this will only work for a page generated from a GET request.