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.
Related
I have a URL, for example this:
https://r6---sn-vgqsrn76.googlevideo.com/videoplayback?expire=1566535969&ei=wRxfXezPAoORV-3ogpgK&ip=185.27.134.50&id=o-ALFdSvuvmX_bqDsm4oRW7q9c4igbKlBmECWdISuA4Jxe&itag=22&source=youtube&requiressl=yes&mime=video%2Fmp4&ratebypass=yes&dur=624.175&lmt=1529213992430932&fvip=6&c=WEB&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cmime%2Cratebypass%2Cdur%2Clmt&sig=ALgxI2wwRAIgZzTTsBPpVznwCvzArBFuSF7Bm3yhcO0rwQdfOjBibnsCIBqf8iHuAwahqi0T6qZ3MNbj8BfLgGo2Y3fPOi96RgEV&redirect_counter=1&cm2rm=sn-aigeey7d&req_id=8f890b1c72fda3ee&cms_redirect=yes&mip=2607:fea8:4d9f:fa68:40a2:35d0:8863:2d17&mm=34&mn=sn-vgqsrn76&ms=ltu&mt=1566514280&mv=m&mvi=5&pl=41&lsparams=mip,mm,mn,ms,mv,mvi,pl&lsig=AHylml4wRQIgSCcxaGd_IpVykCuglJtHwewUuZZIyKKr1FBbNP5MvqsCIQCYQEUoM9SpfpySHA_13lB6SvevIuMvhyFDEcrsX0y0ig==
How can I download the video in this URL programmatically through JavaScript? I cannot use PHP, Apache, JQuery etc, only Pure JavaScript and HTML.
I have tried using download.js, but I do not think that is the right approach to download videos. I have also looked/tried at various other websites and Stack Overflow answers, but none of them fixed this issue.
EDIT: The other SO answer that someone suggested will not work since the video is on a different baseurl than my own, which means that
<a href="file" download="filename">
will not work on Chrome. Doing this just opens the video.
function downloadImage() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://via.placeholder.com/150', true);
xhr.responseType = 'blob';
xhr.onload = function () {
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL(this.response);
var tag = document.createElement('a');
tag.href = imageUrl;
tag.target = '_blank';
tag.download = 'sample.png';
document.body.appendChild(tag);
tag.click();
document.body.removeChild(tag);
};
xhr.onerror = err => {
alert('Failed to download picture');
};
xhr.send();
}
I found the solution to the problem. The link was a YouTube source video link that I was trying to download, and on all videos (except the ones with music or the music genre) all you needed to do was to add
&title=[NAME OF FILE HERE]
which would download the video.
Edit: Downloading these videos worked with download.js. You need to make a XMLHTTP request to the video to get the data, and then use the function
download(data, name, mime)
For more documentation, look on the download.js GitHub page.
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!
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
I am doing a chrome extension capable of getting from a webpage an image, and after I got it, I'm trying to upload it to an intranet server automatically without user iteration.
I am doing this right now.
This is on Content_script.js
...
x = $(frame1).contents().find("#image");
chrome.extension.sendRequest(x[0].src);
...
This is on background.js
chrome.extension.onRequest.addListener(function(links) {
chrome.downloads.download( { url: links ,
conflictAction: "overwrite",
filename: "get_image.jpg" },
function(DescargaId) {
var formData = new FormData();
formData.append("doc", Blob, "~/Downloads/get_image.jpg");
var request = new XMLHttpRequest();
request.open("POST", "http://192.168.0.30/app_get_pictures/upload_img.php");
request.setRequestHeader("Content-Type", "multipart/form-data");
request.send(formData);
} );
This on upload_img.php
...
$uploaddir = $_SERVER['DOCUMENT_ROOT'].'/app_get_pictures/images/';
$uploadfile = $uploaddir . basename($_FILES['doc']['name']);
move_uploaded_file($_FILES['doc']['tmp_name'], $uploadfile);
...
With this, I already download the image successfully to the local machine, but can't upload the image to the server.
It is possible to do this, or even if I can upload the image to the server directly without download it first to the local machine.
Note: I don't have any tag form on a popup page in the extension solution, and I don't have a popup page neither, because as I already said, I don't need any iteration from the user.
Thanks for your help!
Thanks to https://stackoverflow.com/users/934239/xan I resolved this problem using his advise, here is the resulting working code.
...
// With this I can download or get content image into var blob
var xhr = new XMLHttpRequest();
var kima = $(frame1).contents().find("#image");
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'});
send_image(blob);
}
};
xhr.send();
....
// After the image is loaded into var blob, it can be send
// to the server side
function send_image(x){
var formData = new FormData();
formData.append("doc", x);
var request = new XMLHttpRequest();
request.open("POST", "http://192.168.0.30/app_get_image/upload_img.php");
request.send(formData);
}
All this code into the content_script of the chrome extension. Also the code of the background using API download isn't needed anymore.
Hope this could works for anybody else.
Thanks again.
Besides the fact that the callback of downloads.download does NOT indicate that the file is already downloaded (only that the download is queued)..
formData.append("doc", Blob, "~/Downloads/get_image.jpg");
What do you think this code does? Documentation, for reference.
The second parameter is supposed to hold the data of the file; the third parameter is just the file name for the purposes of naming anonymous data (e.g. in a Blob)
Instead, you pass the Blob object itself; not an instance of Blob with the data.
In fact, with this architecture, you won't be able to upload the file, since at no point does chrome.downloads API give you access to the file's contents, and you can't just access a file on a disk by filename (which is what I think you thought this code would do).
To actually access the data, you need to request it yourself with XHR (or Fetch API if you want to be "modern"). Then, you get the response object which you can request to be a Blob. Then, you can both upload the blob and invoke chrome.downloads together with createObjectURL to "download" it from your extension's memory.
I am using an example found here. Mozilla developers
I am interested in this example.
function upload(postUrl, fieldName, filePath)
{
var formData = new FormData();
formData.append(fieldName, new File(filePath));
var req = new XMLHttpRequest();
req.open("POST", postUrl);
req.onload = function(event) { alert(event.target.responseText); };
req.send(formData);
}
But I can't understand what goes where on this example. filePath is understandable but postUrl , fieldName I can find. I am working on image uploading on the page that has Drag and Drop zone for image uploading. How can I use this function to upload the image on my website?
Check out the FormData documentation and XMLHttpRequest documentation.
fieldName The name of the (form) field whose data is contained in value.
postUrl The URL to which to send the request.
You should have a server-side endpoint that responds to the upload request.
For example:
upload('http://mysite.com/uploader.php', 'fileField', 'path/to/my/file.jpg');
Then if you are using PHP on the server-side; you can access that field value on the server-side like this:
$my_files = $_FILES['fileField'];