Downloading and then uploading files with JavaScript - javascript

Now first of all, I'm making a UserScript, meaning that I don't own the servers from which I download files or the servers to which I upload files.
So I need to download a file from a server (needs to be any type, not just text files), and then somehow submit that file to a file upload form on another website. Is that possible? At first I was wondering if I'd be able to submit the file directly from one server to the other, but I don't think that's possible.
So is there any way I can do this? I can use jQuery as well.

As long as you won't be blocked by XSS prevention, load the data using an XMLHttpRequest then post it to the other site.
Here is a very basic functional example:
var xhr = new XMLHttpRequest();
xhr.open("get", "http://www.example.com/file", true);
xhr.onload = function () {
xhr.close();
var xhr2 = new XMLHttpRequest();
xhr2.open("post", "http://www.example2.com/form", true);
xhr2.send(xhr.response);
}
xhr.send();
I would advise that you add some code to catch errors
For more details on XMLHttpRequests, the documentation can be found on MDN here, with instructions on how to use it on MDN here

Related

Read a file in same directory as the JavaScript file

I can load an image file located in the same relative path as the JavaScript file
var imgObj = new Image();
imgObj.src = "images/backdropLevel0.jpg";
But how do I do the same (as simply and with pure JavaScript) for a text file ? (it has some initial data for a webGL game I am working on).
PS. I am not asking about user input from the client's computer using the new File object.
Fetching an image is easy since the browser takes care of all the fetching and rendering. However, loading an arbitrary file into your script requires a couple more lines:
var req = new XMLHttpRequest();
req.onload = function(){
process_webgl_data(this.responseText);
};
req.open('GET', './webgl_init.dat');
req.send();
Where process_webgl_data is whatever you want to do with the text of the file.
EDIT: Two quick things. Remember that request URIs are resolved with respect to the html file rather than the script, and second, here's the documentation for XHR.
You can also archive the same using fetch JavaScript API
Example:
fetch('./webgl_init.dat').then(r=>r.text()).then(process_webgl_data)

Simple JSZip - Create Zip File From Existing Images

I'm having a hard time finding easy documentation for JSZip that doesn't involve Base64 or NodeJS. Basically, I have a directory, in which is test.html and a folder called "images". Inside that folder is a bunch of images. I would like to make a zip file out of that folder.
Can anyone help me with some very simple "hello world" type code for this? The documentation on http://stuk.github.io/jszip/ includes things like adding an image from Base64 data or adding a text file that you create in JavaScript. I want to create a .zip file from existing files.
Perhaps the only support for adding images to .zip files with JSZip involves adding them via Base64 data? I don't see that anywhere in the documentation, nor an image-url-to-base64 function, though I did find one elsewhere on StackOverflow.
Any advice?
In a browser you can use an ajax request and use the responseType attribute to get an arraybuffer (if you need IE 9 support, you can use jszip-utils for example) :
var xhr = new XMLHttpRequest();
xhr.open('GET', "images/img1.png", true);
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = function(evt) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var zip = new JSZip();
zip.file("images/img1.png", xhr.response);
}
}
};
xhr.send();
This example is limited because it handles only one file and manually creates the xhr object (I didn't use any library because you didn't mention any) but should show you how to do it.
You can find a more complete example in the JSZip documentation : it uses jQuery promises and jszip-utils to download a list of files and trigger a download after that.
If you use a library to handle the ajax request, be sure to check if you can ask for an arraybuffer. The default is to treat the response as text and that will corrupt your images. jQuery for example should support it soon.

File download option using clientside script within client system

We are currently working on giving download option to the users to download MP3 files.
We are developing an application that fully execute in local system that no server is required.
But downloading mp3 files option is not working in most of the browsers. Its get opened in inbuilt media players in most browsers.
We have checked the solutions for this as we get answers like setting 'content-disposition' using header in server side or using PHP or ASP scripts to make it downloadable.
I have also checked jquery filedownload.js plugin. that also had a section like setting content-disposition and set-cookie.
So I want to know is it possible to create a file download link (for MP3)* compatible for all browsers using only client side scripts like Javascript or jQuery.
Important note:
Actually the process is not downloading file from a server but from client system itself.
That is the MP3 file should copy from from one location(Directory) to another location with in the client system.
This solution requires browser support of XHR2 (http://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html)
It will download the MP3 into a blob and then will create a URL you can access the blob. During this process you can override the Mimetype to whatever you need.
window.URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://robtowns.com/music/blind_willie.mp3', true);
xhr.responseType = 'blob';
xhr.overrideMimeType('application/octet-stream');
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
$('#link').html('Download');
}
};
xhr.send();
The JSfiddle example requires you to have turned off web-security in your browser to allow a cross domain request.
http://jsfiddle.net/D2DzR/3/

How do I change a filename on-download with javascript?

The script adds a download link for videos (on a specific site). How do I change the filename to something else while downloading?
Example URL:
"http://website.com/video.mp4"
Example of what I want the filename to be saved as during download:
"The_title_renamed_with_javascript.mp4"
This actually is possible with JavaScript, though browser support would be spotty. You can use XHR2 to download the file from the server to the browser as a Blob, create a URL to the Blob, create an anchor with its href property set to that URL, set the download property to whatever you want the filename to be, and then click the link. This works in Google Chrome, but I haven't verified support in other browsers.
window.URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest(),
a = document.createElement('a'), file;
xhr.open('GET', 'someFile', true);
xhr.responseType = 'blob';
xhr.onload = function () {
file = new Blob([xhr.response], { type : 'application/octet-stream' });
a.href = window.URL.createObjectURL(file);
a.download = 'someName.gif'; // Set to whatever file name you want
// Now just click the link you created
// Note that you may have to append the a element to the body somewhere
// for this to work in Firefox
a.click();
};
xhr.send();
You can't do this with client-side JavaScript, you need to set the response header...
.NET
Response.AddHeader("Content-Disposition", "inline;filename=myname.txt")
Or PHP
header('Content-Disposition: inline;filename=myname.txt')
Also available in other server-side languages of your choice.
The filename for downloading is set in the header (take a look at "Content-Disposition"), wich is created on server-side.
There's no way you could change that with pure javascript on a file you're linking to unless you have access to the server-side (that way you could pass an additional parameter giving the filename and change the server-side behaviour to set the header to match that... but that would also be possible with pure html, no need for javascript). Conclusion: Javascript is absolute useless to achive what you want.
You can probably do this with a Chrome userscript, but it cannot be done (yet) with Greasemonkey (Firefox) javascript.
Workaround methods (easiest to hardest):
Add the links with Greasemonkey but use the excellent DownThemAll! add-on to download and rename the videos.
Download the videos as-is and use a batch file, shell-script, Python program, etc. to rename them.
Use Greasemonkey's GM_xmlhttpRequest()Doc function to send the files to your own web application on a server you control.
This server could be your own PC running XAMPP (or similar).
Write your own Firefox add-on, instead of a Greasemonkey script. Add-ons have the required privileges, Greasemonkey does not.
AFAIK, you will not be able to do this right from the client itself. You could first upload the file onto the server with the desired name, and then serve it back up to the end user (in which case your file name would be used).
Just in case you are looking for such a solution for your nasty downloading chrome extension, you should look into chrome.downloads API, it needs additional permission ('downloads') and allows you to specify filename. https://developer.chrome.com/extensions/downloads
However there is a problem I'm facing right now. The chrome extension I'm refactoring has 600k+ user base and adding a new permission would disable the extension for all of them. So it is no-go solution for me, but if you are developing a new extension you definitely should use it.

How can I emulate a form submission with a javascript File object?

So I have a file object created from a drag and drop into an area from desktop. Now things all dandy, until I have to upload it via Ajax to a Django backend. I would like to utilize the nice Django utils such as request.FILES, etc.
Right now, I'm messing with some existing code here:
xhr.open("post", s.post, true);
// Set appropriate headers
xhr.setRequestHeader("content-type", "multipart/form-data");
xhr.setRequestHeader("x-file-name", file.fileName);
xhr.setRequestHeader("x-file-size", file.fileSize);
xhr.setRequestHeader("x-file-type", file.
xhr.send(file);
Try as I might, it doesn't seem to be emulate a form with a file input submission. Is there something that I am missing?
Thanks!
You need to create a "FormData" object and then append the file to that as a parameter.
var fd = new FormData();
fd.append("theFile", yourFileObject);
//
// ... set up the xhr ...
//
xhr.send(fd);
Obviously this only works in HTML5 environments, but if you're messing with the File stuff that's probably something you're dealing with.
Unfortunately, you cannot upload a file using the XmlHttpRequest object because it is not supported.
There have been hacky workarounds (like using an iFrame) and recently there is a new File api (https://developer.mozilla.org/en/using_files_from_web_applications) for HTML 5 for browsers that support it.
If you search a little more on stackoverflow, you can find examples on how to do the workarounds.

Categories

Resources