How to get image from html document retrieved with XMLHttpRequest? - javascript

I want to get the first image of an external webpage and then display it. I use a XMLHttpRequest to get the document from the webpage, then I search for the first image in that document then display it. But no image shows up. This is for a chrome app, not a web page/website. Here is my javascript:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://ab.reddit.com/', true);
xhr.responseType = 'document';
xhr.onload = function(e) {
var ext_doc = this.response;
var img_src = ext_doc.getElementsByTagName("img")[0];
var img_html = document.querySelector('#TestImage2');
img_html.src = img_src.src;
};
xhr.send();

I figured out the issue. I cannot directly set the image src to the retrieved url src of the external image from the external html document. I have to send another XMLHttpRequest for the newly found image scr url and retrieve it as a blob. Then set the image src to window.URL.createObjectURL(this.response). this.response being the image blob. I am not quite sure why it has to be done this way, probably for some security reason. I also put this into its own function. The pgURL parameter is the url of the web page for images to be retrieved. index is the index of the image wanted in the list of all the images on the web page. And display is the image html element to be changed.
function getImage(pgURL, index, display)
{
var xhr = new XMLHttpRequest();
xhr.open('GET', pgURL, true);
xhr.responseType = 'document';
xhr.onload = function(e) {
var doc = this.response;
var img_src = doc.getElementsByTagName("img")[index];
var src = img_src.src;
//Have to make a new XMLHttpRequest for the image found because img sources cannot be directly set
var xhr2 = new XMLHttpRequest();
xhr2.open('GET',src);
xhr2.responseType = 'blob'; //Must make blob object of retrieved image
xhr2.onload = function(e){
display.src = window.URL.createObjectURL(this.response); //Finally set the src for the image
};
xhr2.send();
};
xhr.send();
}
REMINDER! This is for a chrome app, not a website.

Related

Load TIF/TIFF in HTML5 canvas and avoid download

I want to show tiff/tif images inside an HTML5 canvas. Following this doc I´ve accomplished to do it with uploaded images but when I need to dynamically reference external images by URL the browser always force the download.
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.open('GET', "url/of/a/tiff/image/file.tiff");
xhr.onload = function (e) {
var tiff = new Tiff({buffer: xhr.response});
var canvas = tiff.toCanvas();
document.body.append(canvas);
};
xhr.send();
At the begining I had CORS issues but I solved that problem, now the uploaded images are display correctly but URL are not.
How can I do this for both cases uploaded images and URL
Thanks in advance!
UPDATE!
Working on later I noticed that when load .tiff files there is no problem. The download is forced when is a .tif file. Are these mime types differents?

Google Chrome extensions - Get images from cache

I am reprogramming a Google Chrome extension, it was able to download an image using the src attribute, but now, the page change the way it shows the image, it use in the src attribute some kind of script that in background changes the image, getting a different image that web page is showing. I can see the image that I need but using "ChromeCacheView" of NIRSOFT, but it's a desktop solution, so it can't help to do it in the Chrome extension.
Someone could help me, please!
This code below is what I'm using now, but as I said already, it can't show me the web page image is showing.
var xhr = new XMLHttpRequest();
// I think here is where I need the change Getting this ID from cache
var kima = $(frame1).contents().find("#ccontrol1");
xhr.open('GET',kima[0].src,true);
//
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = new Blob([this.response], {type: 'image/png'});
kym_send_image(blob);
kym_process01();
}
};
xhr.onerror = function (e) {
window.location.href = url1;
return;
};
xhr.send();
Well you need to use request.fetch,
You could replace your code with this one below
fetch(kima[0].src,{cache : "force-cache"}).then(r => r.blob({type: 'image/jpg'})).then(blob => function_to_catch_blob(blob));
Hope this could help you!

How to download an image with Python 3/Selenium if the URL begins with "blob:"?

When using web.whatsapp.de one can see that the link to a recieved image may look like this:
blob:https://web.whatsapp.com/3565e574-b363-4aca-85cd-2d84aa715c39
If the link is copied in to an address window it will open up the image, however - if "blob" is left out - it will simply open a new web whatsapp window.
I am trying to download the image displayed by this link.
But using common techniques such as using request, or urllib.request or even BeautifulSoup always struggle at one point: The "blob" at the beginning of the url will throw an error.
These answers Download file from Blob URL with Python will trhow either the Error
URLError: <urlopen error unknown url type: blob>
or the Error
InvalidSchema: No connection adapters were found for 'blob:https://web.whatsapp.com/f50eac63-6a7f-48a4-a2b8-8558a9ffe015'
(using BeatufilSoup)
Using a native approach like:
import requests
url = 'https://web.whatsapp.com/f50eac63-6a7f-48a4-a2b8-8558a9ffe015'
fileName = 'test.png'
req = requests.get(url)
file = open(fileName, 'wb')
for chunk in req.iter_content(100000):
file.write(chunk)
file.close()
Will simply result in the same error as using BeautifulSoup.
I am controlling Chrome using Selenium in Python, however I was unable to download the image correctly using the provided link.
A blob is a filelike object of raw data stored by the browser.
You can see them at chrome://blob-internals/
It's possible to get the content of a blob with Selenium with a script injection. However, you'll have to comply to the cross origin policy by running the script on the page/domain that created the blob:
def get_file_content_chrome(driver, uri):
result = driver.execute_async_script("""
var uri = arguments[0];
var callback = arguments[1];
var toBase64 = function(buffer){for(var r,n=new Uint8Array(buffer),t=n.length,a=new Uint8Array(4*Math.ceil(t/3)),i=new Uint8Array(64),o=0,c=0;64>c;++c)i[c]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charCodeAt(c);for(c=0;t-t%3>c;c+=3,o+=4)r=n[c]<<16|n[c+1]<<8|n[c+2],a[o]=i[r>>18],a[o+1]=i[r>>12&63],a[o+2]=i[r>>6&63],a[o+3]=i[63&r];return t%3===1?(r=n[t-1],a[o]=i[r>>2],a[o+1]=i[r<<4&63],a[o+2]=61,a[o+3]=61):t%3===2&&(r=(n[t-2]<<8)+n[t-1],a[o]=i[r>>10],a[o+1]=i[r>>4&63],a[o+2]=i[r<<2&63],a[o+3]=61),new TextDecoder("ascii").decode(a)};
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.onload = function(){ callback(toBase64(xhr.response)) };
xhr.onerror = function(){ callback(xhr.status) };
xhr.open('GET', uri);
xhr.send();
""", uri)
if type(result) == int :
raise Exception("Request failed with status %s" % result)
return base64.b64decode(result)
bytes = get_file_content_chrome(driver, "blob:https://developer.mozilla.org/7f9557f4-d8c8-4353-9752-5a49e85058f5")
Blobs are not actual files to be remotely retrieved by a URI. Instead, they are programatically generated psuedo-URLs which are mapped to binary data in order to give the browser something to reference. I.e. there is no attribute of <img> to provide raw data so you instead create a blob address to map that data to the standard src attribute.
From the MDN page linked above:
The only way to read content from a Blob is to use a FileReader. The following code reads the content of a Blob as a typed array.
var reader = new FileReader();
reader.addEventListener("loadend", function() {
// reader.result contains the contents of blob as a typed array
});
reader.readAsArrayBuffer(blob);
For people who are trying to do the same in node and selenium, please refer below.
var script = function (blobUrl) {
console.log(arguments);
var uri = arguments[0];
var callback = arguments[arguments.length - 1];
var toBase64 = function(buffer) {
for(var r,n=new Uint8Array(buffer),t=n.length,a=new Uint8Array(4*Math.ceil(t/3)),i=new Uint8Array(64),o=0,c=0;64>c;++c)
i[c]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charCodeAt(c);for(c=0;t-t%3>c;c+=3,o+=4)r=n[c]<<16|n[c+1]<<8|n[c+2],a[o]=i[r>>18],a[o+1]=i[r>>12&63],a[o+2]=i[r>>6&63],a[o+3]=i[63&r];return t%3===1?(r=n[t-1],a[o]=i[r>>2],a[o+1]=i[r<<4&63],a[o+2]=61,a[o+3]=61):t%3===2&&(r=(n[t-2]<<8)+n[t-1],a[o]=i[r>>10],a[o+1]=i[r>>4&63],a[o+2]=i[r<<2&63],a[o+3]=61),new TextDecoder("ascii").decode(a)
};
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.onload = function(){ callback(toBase64(xhr.response)) };
xhr.onerror = function(){ callback(xhr.status) };
xhr.open('GET', uri);
xhr.send();
}
driver.executeAsyncScript(script, imgEleSrc).then((result) => {
console.log(result);
})
For detailed explanation, please refer below link
https://medium.com/#anoop.goudar/how-to-get-data-from-blob-url-to-node-js-server-using-selenium-88b1ad57e36d

Forcing Ajax to get cached version

I am creating a Google-Chrome extension and I want to be able to pull some images that a website is loading and put them in the extension. In some cases, this can result in a lot of requests to the server, effectively slowing it down. These images are loaded when the user visits the page, so there is no need for the extension to request the images again. Is there any way to get the data without pulling the data from the server again?
Using binary Ajax, you can pull the images as Blob objects, which FileReader can convert to a base64 URL string.
Fetch the binary data of the image as an ArrayBuffer and store it in a Blob:
var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";
oReq.onload = function(oEvent) {
var blob = new Blob([oReq.response], {type: "image/png"});
// step 2 goes here...
};
oReq.send();
(According to the spec, you can also do oReq.responseType = "blob" to make oReq.response a Blob immediately, instead of an ArrayBuffer. I'm not 100% sure if this is actually supported yet.)
Read the Blob with FileReader:
var fr = new FileReader();
fr.onload = function(e) {
var dataUrl = e.target.result;
// step 3 goes here...
}
fr.readAsDataURL(blob);
Finally, you have the URL stored in dataUrl. Assign it directly to the src attribute of an image element:
document.getElementById("myimg").src = dataUrl;
To avoid performing the fetch in the future, store the data URL in localStorage or an IndexedDB store.

Get Image from sourceUrl using javascript

I am writing a chrome extension. I want to send an image on some webpage to my site.
Using chrome contextMenus, I can get the source url of that image. I want to know how to use that source to download it or to send it somewhere else. ( similar to save-as functionality provided by browser)
Here's what I would to to upload the URL of an image through context menus:
chrome.contextMenus.onClicked.addListener(function (info) {
var data = new FormData();
data.append('url', info.srcUrl);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://mywebsite.com', true);
xhr.onload = function(e) { console.log(e); }
xhr.send(data);
});
Hope it helps.

Categories

Resources