Using html5 javascript, how do you get the file path when user select the file?
I needed the file path to use in this example case:
user upload a file, pause it(I know so far I think only mozilla can do this), and then close the browser and plan to resume the file the next day. I need to know the file path for this file..
Even if you did have a path (some browsers used to give it to you), there is no way to set the path of a input of type file.
Therefore, it is not possible to do what you want with plain JS and the DOM.
I said it wasn't possible, but now that you asked I do think there is a way, with new File API. The following steps outline what needs to be done, but have in no way been tested, and I don't expect it to work, it's just to show you the way, also global variables are bad, it's just the simplest way to show you. Here's a good page with examples on using the File API http://www.html5rocks.com/en/tutorials/file/dndfiles/
First You need an input of type file, then you can use once a user selects a file, you are given access to the File object. http://dev.w3.org/2006/webapi/FileAPI/#dfn-filereader
<input type="file" id="files" name="files[]" multiple />
<script>
var fileBlobs = [];
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// files is a FileList of File objects. You may now read their contents
var reader = new FileReader();
for (var i = 0, f; f = files[i]; i++) {
fileBlobs.push(reader.readAsBinaryString(f));
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
Second Now you have the content as a binary string. You can use the File API to store the file locally in a way that you can access later using the FileWriter and FileSaver interfaces http://dev.w3.org/2009/dap/file-system/file-writer.html
var bb = new BlobBuilder();
bb.appendfileBlobs.(fileBlobs[0]);
window.saveAs(bb.getBlob(), "test_file");
Third You need to make an Ajax request passing that blob to the server, tracking how much of the upload is complete. http://www.w3.org/TR/XMLHttpRequest/#the-upload-attribute. It doesn't look like tracking progress can be done on the client. Your may have to poll the server for actual progress. A possible solution to know where to start an interrupted upload is to have upload ids and when you restart an upload, you ask the server how much of the file has been uploaded.
Sorry I can't provide a full answer, but this is not an easy problem. The steps I gave you should take you in the right direction.
Much like you can't submit an HTTP request in pieces over several days, you can't do it with file uploads as well. The protocol just won't allow it. Hence the entire effort is futile.
As far as I know, that isn't possible as Javascript only has access to files that were shared with it through either a file input or drag-and-drop.
Related
I'm new to the Google Drive API and I've been using it in a sort of an unorthodox manner. Right now I have just an API key to authenticate and I download files using the https://www.googleapis.com/drive/v3/files/file-id?alt=media&key=api-key scheme. This can successfully download files, except that their name is actually just the file ID without any extension. I've tried a few things so far including setting headers in my PHP code that define content-type, content-disposition, and even content-length attributes, but that used my server's bandwidth even if used properly. I've also tried that HTML download attribute for a tags, but I found it only works with blobs or local files. I've also tried some Javascript to no avail. Here is part of my code right now, which uses blobs to download and rename the file, however I would like to not have to go this route and seek a better option:
<?php
$id = "SOME-ID-HERE";
$key = "API-KEY-HERE"; // Google Drive API Key
$pre = "https://www.googleapis.com/drive/v3/files/";
$dlink = $pre.$id."?alt=media&key=".$key;
?>
<script type="text/javascript">
window.URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest(),
a = document.createElement('a'), file;
xhr.open('GET', '<?php echo $dlink ?>', true);
xhr.responseType = 'blob';
xhr.onload = function () {
file = new Blob([xhr.response], { type : 'application/octet-stream' });
a.href = window.URL.createObjectURL(file);
a.download = 'filename.ext';
a.click();
};
xhr.send();
</script>
As you can see, I'm not even using the Drive API PHP libraries, I'm just using their link which either returns the file contents or the metadata of the file. I suspect that this is why the file being downloaded is renamed to just the file ID, but I don't know for sure. Since I don't want to use blobs unless I have to, my main question is: Can I use the Drive API (properly by including the PHP libraries for it) to download files from Google Drive, but have them be named exactly as how they are already named in Google Drive? Secondly, if this is possible, does it use my server's bandwidth for serving the files or is it directly from Google's servers? I want to try to avoid using my server's bandwidth if possible to accomplish this.
UPDATE: I have a server here that works for this but it's a hacky method of getting it to work. I would still feel safer using the API because it's future proof.
https://drivedl.cf/file-id
I wouldn't recommend using it yet though, it works but there's some potential bugs I need to weed out
UPDATE 2: https://drivedl.cf/file-id is currently unusable because I'm working on it right now, trying to use the API but It's giving me issues
I actually want to upload an image to a server.
To achieve this, i want the user just paste the image into chrome (the image is a print screen in fact), and then i post the stream to a php page, convert the stream as an image, and then upload it.
How can i achieve this web application ?
Today i have develop some differents parts :
I used this script, and i create the Upload.php page which gets the post variable and try to Create and image.
The problem i have, is that when i post the data, i only get a blob. I would like to get a base64 stream.
Can you help me ?
Thanks in advance.
I'm not sure why you are specifically looking for a "base 64 stream". If you are sending the Blob to your server via ajax, as far as your server is concerned, it's a file. Treat it no different than any other upload server-side. A Blob is a File without a name property. That's perhaps a bit overly-simplistic, but my point is that, again, this is really nothing more than a file as far as your server knows.
Assuming you are sending a multipart-encoded request, I'd like to point out that most user agents will set the filename property of the item's Content-Disposition header in the request to "blob" when the item you are uploading is a Blob instead of a file. It is possible to change this value in some browsers via the 3rd argument in FormData's append method, but I wouldn't rely on this just yet.
Also note that, if you are interested in a library that handles all of this already, I maintain, Fine Uploader which natively supports uploading images via paste in Chrome.
To answer this old question: Posting an image from clipboard with chrome is pretty much the same as posting a dropped file - except that the image/blob doesn't have the properties "name" and "lastModified".
var entry = items[i].webkitGetAsEntry();
if (!entry) entry = items[i].getAsFile();
if (entry instanceof Blob) /** CHROME pastet Bilder als Blob **/
{
entry.isFile = true;
entry.lastModifiedDate = new Date();
entry.name = ""+new Date().getTime()+"."+entry.type.split('/')[1];
}
if (entry.isFile)
{
//handle dropped file
}
So my application generates pdf files using TCPDF, and that works fine. That is done inside php file, called with ajax. I'm using embed tag to preview them like:
$.ajax({
url: 'create_pdf_file.php',
success: function(){
/* https://stackoverflow.com/questions/17083018/jquery-loads-cached-file-inside-ajax-success-function */
$('#pdf_placeholder embed').attr('src','output/my_file.pdf?v=' + Math.random()');
}
});
Because many users could generate my_file.pdf at the same time, there could be a case when one user will preview a file generated for another user. So my question at this point is how to force TCPDF to output directly into that tag, not using temp file
Output('my_file','I')
not working here after ajax.
There is an advice here to echo pdf directly back, but i don't know how to do that or is it possible at all. Anyway will try with success(data) to receive that like json.
Other workaround is to give session-bond file name for each user, but is using session_id() and appending to the file name is safe? Most probably I will end with generating UID for each session.
Any general advices are welcome.
You should try passing what TCPDF will produce in a way widely used in embeding images: Data Uri
Embedding Base64 Images
This however might choke browser - i haven't test this.
I would rather save pdf file on server, print filename to browser or other ID of produced file so it could be read with "success" of the ajax request. Then calmly pass proper filename to Embed element. If you wish to do it more safely you can encode it using already used session-exclusive data like session cookie or data that is assosiated with that cookie on a server. You can bond pdf file access to IP that sent request to produce it and timestamp of request that caused production.
This is continued from my original question (http://stackoverflow.com/questions/10133976/getelementsbytagname-specific-links-only) which I got resolved but now facing different issue.
I'm implementing Anarchy player on my site and problem is that script stores files outside the domain root so links to them are in format like ( http: // mysite.com/mod/file/download.php?file_guid=fileID) which is fine for the player, it still plays the file but I need to separate files by type.
Look at the javascript code below, "if(o.href.match(/.mov$|.mp4$|.m4v$|.m4b$|.3gp$/i)" part, if I understand it correctly it says if file extension is .mov, .mp4, etc. than include that player. But since link is not in standard format with file name and extension it does not recognize it.
How to change that "if(o.href.match" to something that would distinguish what type of file it is?
I can pull file full name with extension in text format via PHP code and maybe wrap it in or div and that use if...div.match(...?
Link to video file is already inside div block id "video"
<div id="video">
</div>
Here is javascript:
var all = document.getElementById ( "video" ).getElementsByTagName ( "a" );
for (var i = 0, o; o = all[i]; i++) {
if(o.href.match(/\.mov$|\.mp4$|\.m4v$|\.m4b$|\.3gp$/i) && o.className!="amplink") {
Thank you so much for any suggestions.
It's not always possible to decide upon the filetype of a file just by looking at the filename. A better approach is to look at the Content-Type header (in case of an HTTP resource) or the MIME-type (which is essentially the same thing).
It's still possible to send a bad Content-Type so perhaps there is a way to identify the filetype by looking at the first few bytes? I know PNG starts with a very obvious indicator.
I want let user to upload images to server add some info (like description, tags) about each image.I use Uploadify to upload multiple images.
I wonder if it is possible to show thumbnails of the images (while the user enters the additional info about each image) before the images are actually uploaded to the server.
I want user to have the following experience:
Select multiple image files
Immediately after that enter additional information about each image while seeing images thumbnails
Press Upload Files button to upload images to server, and go to drink coffee...
I found this script, but I think it also uploads the file before displaying the image thumbnail.
I would appreciate any help !
If you could enforce an HTML 5 capable browser you could use the file-api
Example: http://html5demos.com/file-api
Sure it is possible. Use the FileReader object to get a data URL (or use File.url if you are sure the Client implements it.) and assign it to an new Image()object. Then you can insert the image into DOM.
As an alternative to the standard-based HTML5 APIs, you can use a plugin such as Flash or Browserplus.
There is actually a ready-made application which might do exactly what you want. It's called Plupload. You can upload your files / images using a variety of "runtimes", and do client-side image resizing before uploading. I guess you can hook a thumbnail preview somewhere in there, in certain runtimes.
Otherwise, you can try building what you want from scratch, using the HTML5 / Gears / BrowserPlus / etc. APIs.
I'm pretty sure flash and java can both do it. Flash would require certain (obvious) security precautions (ie, you can do this for any file, it must be selected by the user).
Meanwhile java would show a security popup.
Xavier posted this solution on another thread, and I tried to improove it to work with multiple file inputs. I hope it helps.
$("body").on('change', 'input:file', function(e){
for (var i = 0; i < e.originalEvent.srcElement.files.length; i++) {
var file = e.originalEvent.srcElement.files[i];
var img = document.createElement("img");
var reader = new FileReader();
reader.onloadend = function() {
img.src = reader.result;
}
img.width = "50";
reader.readAsDataURL(file);
if($(this).next().hasClass('image_place')){
$(this).next('.image_place').html('').append(img);
}else {
$(this).after('<div class="image_place"></div>');
$(this).next('.image_place').append(img);
}
}
});
It scans all file inputs in the document body and reads the image using the FileReader api. If it finds any images, it creates a div called "image_place" where he puts the image. If there's already a image inside, the script replaces the image.