Correct HTML upload accept attribute for audio/viso - html

I would like the same input to accept audio/video/image files only.
What is the correct accept attribute value for this?
For images I only need to support gif/jpeg/jpg/png.
currently I am testing this:
accept="image/video/audio/png/gif/jpeg/jpg/mp3/mp4,video/x-m4v,video/*"

You can specify additional MIME types and/or extensions if you need:
accept="video/*,audio/*,image/gif,image/jpeg,image/png,.gif,.jpeg,.jpg,.png"
Documentation: File Upload state (type=file)

Demo Fiddle
function handleFileSelect(evt) {
var validExtensions = ["jpg", "jpeg", "gif", "png", "mp3", "mp4"];
var files = evt.target.files[0];
var ext = files.name.split('.').pop();
if (validExtensions.indexOf(ext) > -1) {
alert("Valid");
} else {
alert("Invalid");
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
This method is based on comparing the extension of the uploaded file with the array of valid extensions. So user can easily validate this by changing the extension of the file.
For ex. Renaming the image.bmp to image.jpg
Reference:
1. For File Extension

Related

Google Picker not selecting by file extension

Given files in Drive with an (arbitrary) extension *.abc, this code...
gapi.load("picker", { "callback": function () {
if (!picker) {
var view = new google.picker.DocsView(google.picker.ViewId.DOCS);
view.setMimeTypes("application/vnd.google.drive.ext-type.abc");
view.setMode(google.picker.DocsViewMode.LIST);
picker = new google.picker.PickerBuilder();
picker.setTitle(TEXT.PICKER_PROMPT);
picker.setAppId(CONST.APP_ID);
picker.addView(view);
picker.setOAuthToken(session.OAuthToken.access_token);
picker.setCallback(pickerCallback);
picker.setInitialView(view);
};
picker.build().setVisible(true);
));
...doesn't find any of the existing 'abc' files in drive.
These files are of mime type text/xml, and the following line DOES find them:
view.setMimeTypes("text/xml");
Why doesn't the search by extension work?
For those finding this from Google, the question wasn't as daft as it sounded - there is a (pseudo) mime-type for each extension in the Drive world, but it's not usable in that way, at least not in the Picker.
A workable (ie user-friendly) solution is to use a query on the view:
view.setQuery("*.abc");
For completeness:
gapi.load("picker", { "callback": function () {
if (!picker) {
var view = new google.picker.DocsView(google.picker.ViewId.DOCS);
view.setMimeTypes("text/xml");
view.setMode(google.picker.DocsViewMode.LIST);
view.setQuery("*.abc");
picker = new google.picker.PickerBuilder();
picker.setTitle(TEXT.PICKER_PROMPT);
picker.setAppId(CONST.APP_ID);
picker.addView(view);
picker.setOAuthToken(session.OAuthToken.access_token);
picker.setCallback(pickerCallback);
picker.setInitialView(view);
};
picker.build().setVisible(true);
));
Adding on to HeyHeyJC's answer, you can use a double pipe (||) separating each file extension, if you want to use multiple.
For example, view.setQuery("*.abc || *.def || *.ghi");

Google chrome extensions for managing Downloads

I am trying to create an extension which puts all the pdf files downloaded by user through browser into a separate directory. Any Api by which can do this or some help on how I can do it would be helpful.
While you cannot easily write to an arbitrary path, you can redirect all PDF files into a subfolder of Downloads folder.
Check out onDeterminingFilename event of chrome.downloads and Filename Controller sample extension. Since you can indicate a relative path instead of a plain filename, this should work.
Note that the file's MIME type should be available in onDeterminingFilename, you can use that.
Code example, as requested:
var folder = "PDF_downloads";
chrome.downloads.onDeterminingFilename.addListener(
function (item, suggest) {
if(isPDF(item)) suggest({filename: folder + "/" + item.filename});
else suggest();
}
);
function isPDF(item){
if(item.mime === "application/pdf") return true;
else if (item.filename.match(/\.pdf$/i)) return true;
else return false;
}
This will not override that the browser tries to open the PDF itself instead of downloading, but attempting to download will suggest that folder.

how to force input type file to accept only .html or .htm files

here i am trying to upload html/htm files on the click of a button. For that i am using 'input type=file' I have set the 'accept' attribute of it to accept only html/htm extensions like this:
<input type="file" name="htmla" id="htmla" accept="text/html" />
But it is showing different behaviour in different browsers
In firefox, it is accepting all files
In chrome, it is accepting html as well as images
In IE, the same as firefox
Is there a way to make it accept only html/htm files by any method like javascript or jquery?
Note: I am using this control in MVC 4
This is HTML5 specific attribute. Not all browsers support it yet. For those that doesn't you will have to perform the check on the server. Another possibility is to check the extension of the file that was selected using javascript. Basically you could get the selected filename like this: $('#htmla').val(). And then regex for the extension.
There is nothing in standard input control by which you can achieve it.
Yes there is an "accept" attribute on file input controls, where you can specify the types of files you want but this is not recognized by many browsers. So the best you can do is check the file name (extension) of file selected by user using Javascript or Jquery.
function ValidateFile() {
var fileName = document.getElementById("inputFileId").value
if (fileName == "") {
alert("upload a valid File with .htm extension");
return false;
}
else if (fileName.split(".")[1].toUpperCase() == "HTM")
return true;
else {
alert("Invalid File");
return false;
}
return true;
}
But there's nothing preventing the user from renaming an executable to .html for example.
<script>
function test(obj,filter){
var file = obj.value.match(/[^\/\\]+$/gi)[0];
var rx = new RegExp('\\.(' + (filter?filter:'') + ')$','gi');
if(filter&&file&&!file.match(rx)){
alert("check the file type, only html is accepted");
//input file
//it's totally a bad idea...
//document.body.innerHTML = "<input type='file' onchange=\"test(this,'html');\" >";
}
}
</script>
<body>
<input id="inputFile" type="file" onchange="test(this,'html');">
</body>
maybe this should be for you swfupload

getting file name from file

I have the following code:
private function uploadFile(file:File, packageId:String):void {
try {
var fullpath:String = file.nativePath;
var filename:String = fullpath.substr(fullpath.lastIndexOf("/")+1,fullpath.length);
packageItem.status = "Uploading file: "+filename;
file.addEventListener(ProgressEvent.PROGRESS, function(event:ProgressEvent):void{uploadProgress(event, packageId)} );
file.addEventListener(flash.events.Event.COMPLETE, function(event:flash.events.Event):void{uploadComplete(event, packageId)} );
file.upload(urlRequest, packageId);
} catch (error:Error) {
logging.log(error.message);
}
}
So i extract the filename from the path in a file object.
the files are comming from:
File.applicationStorageDirectory
The problem is that this isnt working for windows because they are using backslashes instead of slashes like mac osx does. What would be the best way to seperate the filename and file so it works on mac and windows?
Its fairly obvious.
The url property has the filesystem url of the file. So a file with a nativePath of
C:\Documents and Settings\some_file.txt
would have a url of
file:///C:/Documents%20and%20Settings/some_file.txt
Now you just need to split on / and you're done.
P.S.: You might have to unescape the file name to remove the url-type formatting

How to set name of file downloaded from browser?

I'm writing a web application that, among other things, allows users to upload files to my server. In order to prevent name clashes and to organize the files, I rename them once they are put on my server. By keeping track of the original file name I can communicate with the file's owner without them ever knowing I changed the file name on the back end. That is, until they go do download the file. In that case they're prompted to download a file with a unfamiliar name.
My question is, is there any way to specify the name of a file to be downloaded using just HTML? So a user uploads a file named 'abc.txt' and I rename it to 'xyz.txt', but when they download it I want the browser to save the file as 'abc.txt' by default. If this isn't possible with just HTML, is there any way to do it?
When they click a button to download the file, you can add the HTML5 attribute download where you can set the default filename.
That's what I did, when I created a xlsx file and the browser want to save it as zip file.
Download
Download Export
Can't find a way in HTML. I think you'll need a server-side script which will output a content-disposition header. In php this is done like this:
header('Content-Disposition: attachment; filename="downloaded.pdf"');
if you wish to provide a default filename, but not automatic download, this seems to work.
header('Content-Disposition: inline; filename="filetodownload.jpg"');
In fact, it is the server that is directly serving your files, so you have no way to interact with it from HTML, as HTML is not involved at all.
just need to use HTML5 a tag download attribute
codepen live demo
https://codepen.io/xgqfrms/full/GyEGzG/
my screen shortcut.
update answer
whether a file is downloadable depends on the server's response config, such as Content-Type, Content-Disposition;
download file's extensions are optional, depending on the server's config, too.
'Content-Type': 'application/octet-stream',
// it means unknown binary file,
// browsers usually don't execute it, or even ask if it should be executed.
'Content-Disposition': `attachment; filename=server_filename.filetype`,
// if the header specifies a filename,
// it takes priority over a filename specified in the download attribute.
download blob url file
function generatorBlobVideo(url, type, dom, link) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function(res) {
// console.log('res =', res);
var blob = new Blob(
[xhr.response],
{'type' : type},
);
// create blob url
var urlBlob = URL.createObjectURL(blob);
dom.src = urlBlob;
// download file using `a` tag
link.href = urlBlob;
};
xhr.send();
}
(function() {
var type = 'image/png';
var url = 'https://cdn.xgqfrms.xyz/logo/icon.png';
var dom = document.querySelector('#img');
var link = document.querySelector('#img-link');
generatorBlobVideo(url, type, dom, link);
})();
https://cdn.xgqfrms.xyz/HTML5/Blob/index.html
refs
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#important_mime_types_for_web_developers
Sometimes #Mephiztopheles answer won't work on blob storages and some browsers.
For this you need to use a custom function to convert the file to blob and download it
const coverntFiletoBlobAndDownload = async (file, name) => {
const blob = await fetch(file).then(r => r.blob())
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.style.display = 'none'
a.href = url
a.download = name // add custom extension here
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(url)
}
Same code as #Hillkim Henry but with a.remove() improvement
This forces the document to remove the a tag from the body and avoid multiple elements
const coverntFiletoBlobAndDownload = async (file, name) => {
const blob = await fetch(file).then(r => r.blob())
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.style.display = 'none'
a.href = url
a.download = name // add custom extension here
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(url)
// Remove "a" tag from the body
a.remove()
}
Well, #Palantir's answer is, for me, the most correct way!
If you plan to use that with multiple files, then i suggest you to use (or make one) PHP Download Manager.
BUT, if you want to make that to one or two files, I will suggest you the mod_rewrite option:
You have to create or edit your .htaccess file on htdocs folder and add this:
RewriteEngine on
RewriteRule ^abc\.txt$ xyz.txt
With this code, users will download xyz.txt data with the name abc.txt
NOTE: Verify if you have already the "RewriteEngine on " on your file, if yes, add only the second for each file you wish to redirect.
Good Luck ;)
(Sorry for my english)