How to resolve the C:\fakepath? - javascript

<input type="file" id="file-id" name="file_name" onchange="theimage();">
This is my upload button.
<input type="text" name="file_path" id="file-path">
This is the text field where I have to show the full path of the file.
function theimage(){
var filename = document.getElementById('file-id').value;
document.getElementById('file-path').value = filename;
alert(filename);
}
This is the JavaScript which solve my problem. But in the alert value gives me
C:\fakepath\test.csv
and Mozilla gives me:
test.csv
But I want the local fully qualified file path. How to resolve this issue?
If this is due to browser security issue then what should be the alternate way to do this?

Some browsers have a security feature that prevents JavaScript from knowing your file's local full path. It makes sense - as a client, you don't want the server to know your local machine's filesystem. It would be nice if all browsers did this.

Use
document.getElementById("file-id").files[0].name;
instead of
document.getElementById('file-id').value

I use the object FileReader on the input onchange event for your input file type! This example uses the readAsDataURL function and for that reason you should have an tag. The FileReader object also has readAsBinaryString to get the binary data, which can later be used to create the same file on your server
Example:
var input = document.getElementById("inputFile");
var fReader = new FileReader();
fReader.readAsDataURL(input.files[0]);
fReader.onloadend = function(event){
var img = document.getElementById("yourImgTag");
img.src = event.target.result;
}

If you go to Internet Explorer, Tools, Internet Option, Security, Custom, find the "Include local directory path When uploading files to a server" (it is quite a ways down) and click on "Enable" . This will work

I am happy that browsers care to save us from intrusive scripts and the like. I am not happy with IE putting something into the browser that makes a simple style-fix look like a hack-attack!
I've used a < span > to represent the file-input so that I could apply appropriate styling to the < div > instead of the < input > (once again, because of IE). Now due to this IE want's to show the User a path with a value that's just guaranteed to put them on guard and in the very least apprehensive (if not totally scare them off?!)... MORE IE-CRAP!
Anyhow, thanks to to those who posted the explanation here: IE Browser Security: Appending "fakepath" to file path in input[type="file"], I've put together a minor fixer-upper...
The code below does two things - it fixes a lte IE8 bug where the onChange event doesn't fire until the upload field's onBlur and it updates an element with a cleaned filepath that won't scare the User.
// self-calling lambda to for jQuery shorthand "$" namespace
(function($){
// document onReady wrapper
$().ready(function(){
// check for the nefarious IE
if($.browser.msie) {
// capture the file input fields
var fileInput = $('input[type="file"]');
// add presentational <span> tags "underneath" all file input fields for styling
fileInput.after(
$(document.createElement('span')).addClass('file-underlay')
);
// bind onClick to get the file-path and update the style <div>
fileInput.click(function(){
// need to capture $(this) because setTimeout() is on the
// Window keyword 'this' changes context in it
var fileContext = $(this);
// capture the timer as well as set setTimeout()
// we use setTimeout() because IE pauses timers when a file dialog opens
// in this manner we give ourselves a "pseudo-onChange" handler
var ieBugTimeout = setTimeout(function(){
// set vars
var filePath = fileContext.val(),
fileUnderlay = fileContext.siblings('.file-underlay');
// check for IE's lovely security speil
if(filePath.match(/fakepath/)) {
// update the file-path text using case-insensitive regex
filePath = filePath.replace(/C:\\fakepath\\/i, '');
}
// update the text in the file-underlay <span>
fileUnderlay.text(filePath);
// clear the timer var
clearTimeout(ieBugTimeout);
}, 10);
});
}
});
})(jQuery);

On Chrome/Chromium based apps like electron you can just use the target.files:
(I'm using React JS on this example)
const onChange = (event) => {
const value = event.target.value;
// this will return C:\fakepath\somefile.ext
console.log(value);
const files = event.target.files;
//this will return an ARRAY of File object
console.log(files);
}
return (
<input type="file" onChange={onChange} />
)
The File object I'm talking above looks like this:
{
fullName: "C:\Users\myname\Downloads\somefile.ext"
lastModified: 1593086858659
lastModifiedDate: (the date)
name: "somefile.ext"
size: 10235546
type: ""
webkitRelativePath: ""
}
So then you can just get the fullName if you wanna get the path.
Note that this would only work on chrome/chromium browsers, so if you don't have to support other browsers (like if you're building an electron project) you can use this.

I came accross the same problem. In IE8 it could be worked-around by creating a hidden input after the file input control. The fill this with the value of it's previous sibling. In IE9 this has been fixed aswell.
My reason in wanting to get to know the full path was to create an javascript image preview before uploading. Now I have to upload the file to create a preview of the selected image.

If you really need to send the full path of the uploded file, then you'd probably have to use something like a signed java applet as there isn't any way to get this information if the browser doesn't send it.

Use file readers:
$(document).ready(function() {
$("#input-file").change(function() {
var length = this.files.length;
if (!length) {
return false;
}
useImage(this);
});
});
// Creating the function
function useImage(img) {
var file = img.files[0];
var imagefile = file.type;
var match = ["image/jpeg", "image/png", "image/jpg"];
if (!((imagefile == match[0]) || (imagefile == match[1]) || (imagefile == match[2]))) {
alert("Invalid File Extension");
} else {
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(img.files[0]);
}
function imageIsLoaded(e) {
$('div.withBckImage').css({ 'background-image': "url(" + e.target.result + ")" });
}
}

seems you can't find the full path in you localhost by js, but you can hide the fakepath to just show the file name. Use jQuery to get the file input's selected filename without the path

The best solution for this, I've found, is to use a middleware like Multer. Here's a quick rundown:
npm i multer
Add enctype="multipart/form-data" to your html form.
In your backend dock where you're making your post request, require multer (const multer = require('multer'))
In the same dock, set your upload destination: const upload = multer({dest:'uploas/'}). This will automatically create a local folder called 'uploads' where your files will be added. The code I've included shows you how to upload to your local disk storage. If you're using cloud storage (e.g. AWS, Azure, Cloudinary etc.) you can check out the Multer docs to see how to manage that. There aren't too many extra steps though.
in your post request, add 'upload.single' (for one file) or 'upload.array' (for multiple files), like this:
router.post('/new', upload.single('image'), async function(req, res) { //'image' should be the name of the input you're sending in the req.body
console.log(req.file) //note, if you're using 'upload.array', this should be 'req.files'
});
the req.file will have a full path name that you can use in your post request. For more information, check out the Multer docs:
https://www.npmjs.com/package/multer
I hope this helps!

You would be able to get at least temporary created copy of the file path on your machine. The only condition here is your input element should be within a form
What you have to do else is putting in the form an attribute enctype, e.g.:
<form id="formid" enctype="multipart/form-data" method="post" action="{{url('/add_a_note' )}}">...</form>
you can find the path string at the bottom.
It opens stream to file and then deletes it.

Hy there , in my case i am using asp.net development environment, so i was want to upload those data in asynchronus ajax request , in [webMethod] you can not catch the file uploader since it is not static element ,
so i had to make a turnover for such solution by fixing the path , than convert the wanted image into bytes to save it in DB .
Here is my javascript function ,
hope it helps you:
function FixPath(Path)
{
var HiddenPath = Path.toString();
alert(HiddenPath.indexOf("FakePath"));
if (HiddenPath.indexOf("FakePath") > 1)
{
var UnwantedLength = HiddenPath.indexOf("FakePath") + 7;
MainStringLength = HiddenPath.length - UnwantedLength;
var thisArray =[];
var i = 0;
var FinalString= "";
while (i < MainStringLength)
{
thisArray[i] = HiddenPath[UnwantedLength + i + 1];
i++;
}
var j = 0;
while (j < MainStringLength-1)
{
if (thisArray[j] != ",")
{
FinalString += thisArray[j];
}
j++;
}
FinalString = "~" + FinalString;
alert(FinalString);
return FinalString;
}
else
{
return HiddenPath;
}
}
here only for testing :
$(document).ready(function () {
FixPath("hakounaMatata:/7ekmaTa3mahaLaziz/FakePath/EnsaLmadiLiYghiz");
});
// this will give you : ~/EnsaLmadiLiYghiz

Related

Verifying drag & dropped file extension using JavaScript

I created a page that would accept drag & drop method of file upload, however, I couldn't get it to verify whether file extension is correct, and as of right now it simply rejects every file fed to it as "not of the right file extension". Can anyone explain to me why that is and what fixes can be done in order to fix my problem?
I'm using Apache to run my website
Here's my script of what I have tried:
const dropArea = document.getElementById("dropArea");
dropArea.addEventListener("dragover", (event)=>{
event.preventDefault();
dropArea.classList.add("active");
});
dropArea.addEventListener("dragleave", ()=>{
dropArea.classList.remove("active");
});
dropArea.addEventListener("drop", (event)=>{
event.preventDefault();
file = event.dataTransfer.files[0];
showFile(); //calling function
});
function showFile(){
const pheil = document.getElementById('TotalFail');
var filePath = file.type;
let validExtensions = ["application/x-java-keystore", "application/pkcs12"]; //adding some valid extensions in array
if(!validExtensions.includes(filePath)){
dropArea.classList.remove("active");
dropArea.classList.add("upload-fail")
var errorMessage = document.createElement("p")
errorMessage.className = "ErrorMsg"
errorMessage.id = "TotalFail"
if(pheil === null){
var errorTxt = document.createTextNode("Maximum file size exceeded or file extension is incorrect")
errorMessage.appendChild(errorTxt)
var errorDiv = document.getElementById("error-message")
errorDiv.appendChild(errorMessage)
} else {
return;
}
file.value = null;
}else{
alert("things are supposed to happen here")
}
}
What current code does:
Rejecting every file extension fed to it, even the one that's supposed to be the correct file extension
What I expect my code to do:
Correctly validate .jks and .pfx files without fault
P.S.:
I could provide a full html page with all the code if needed. Just in case that this doesn't actually look sensible at all.
Could also be that my complication is that I want my javascript to check for .jks and .pfx file extensions (e-key files) which aren't really super common.
What I have tried:
Rewriting code with different ways of verifying file extensions, none of which worked out for me.
Adding .jks and .pfx file extensions to mime.types and .htaccess
Trying other people's codes.

handling new image file value is undefined in javascript

Working on a small guestbook posting site as part of a course however I've run into a little problem I cannot figure out.
Using a buttion to open file selection, to select an image and then process this file using the data url and create a key from the date.
However, during getting the file my data variable remains undefined all the way through and never receives the information it needs to show the image. and I'm unable to figure out the cause.
Below are the relevant parts.
function addPhotoClick() {
var inputElement = document.querySelector("#image input");
inputElement.click();
}
function processFile(event) {
debugger;
var data = event.target.result;
debugger;
var key = "diary" + Date.now();
debugger;
addImageEntry(key, data);
}
function initalize(){
var addPhotoButton = document.querySelector("#image button");
addPhotoButton.addEventListener("click", addPhotoClick);
}
Any help would be appreciated.
Try accessing file through image_field_id.files[0] instead of event. According to this, every browser which supports HTML5 should support this property.
Btw not sure if you need a button here, <input type="file"> should create one automatically.
And always add related HTML, please, it's not 100% clear how it looks like.

File upload - multiple instances

I've been trying to implement a few file uploader packages (raw php) in a dynamically loaded format, with a potentially unknown number of them on a page. I've pretty much looked at all the popular ones from flash based to everything in between but having the same problem.
I'm currently trying to work with this.
I have tried tricks I've read about like using ^= in getelementbyid and also "\\S*" to ensure that the relevant div id is used by the javascript but I've had no success. I've also tried adding a class name to each div and using the getelementbyclass without success. I've searched all over for a solution but I'm just not getting it.
Either I'm doing it wrong or I'm completely lost ... I'm actually both!
If anyone can put me out of my misery or send me down the right direction I'd really appreciate as I've been trying to find a solution for a while.
The HTML portion is presented like so:
<p id="upload" class="hidden"><label>Drag & drop not supported, but you can still upload via this input field:<br><input type="file"></label></p>
<p id="filereader">File API & FileReader API not supported</p>
<p id="formdata">XHR2's FormData is not supported</p>
<p id="progress">XHR2's upload progress isn't supported</p>
<p>Upload progress: <progress id="uploadprogress" min="0" max="100" value="0">0</progress></p>
<p>Drag an image from your desktop on to the drop zone above to see the browser both render the preview, but also upload automatically to this server.</p>
I intend to dynamically generate it via PHP into something like, where $inc is a php variable in a loop, e.g id="filereader$inc
The issue, I believe is where the javascript will only handle pre-defined or one instance of the uploader untill modified otherwise
E.g: filereader: document.getElementById('filereader')
That Javascript code won't work with multiple instances because it uses the getElementById method which returns only one element (the first match it finds).
It's also worth mentioning that the JS code won't work for many users (about half, I believe) because it relies on the File API which isn't supported by IE9 and below.
To make that code work with multiple instances, it must be either refactored so as not to rely on element IDs, or you must generate multiple copies with unique elment IDs with the server side code. In PHP, that would involve using a for or foreach loop similar to this:
<?php
for (i=0; $i<$something; i++) {
echo <<<EOB
var holder = document.getElementById('holder$i'),
tests = {
filereader: typeof FileReader != 'undefined',
dnd: 'draggable' in document.createElement('span'),
formdata: !!window.FormData,
progress: "upload" in new XMLHttpRequest
},
support = {
filereader: document.getElementById('filereader$i'),
formdata: document.getElementById('formdata$i'),
progress: document.getElementById('progress$i')
},
// snipped for space
EOB;
}
I don't recommend either course of action, primarily because it still won't work at all with a large number of users. Instead, I suggest using a different upload library.
I've been similarly dissatisfied with JS file upload libraries, so I wrote one that supports IE7+ (theoretically IE6, but not tested), progress bars (with fallback options for handling IE9 and below), and allows multiple instances.
It does not, however, support drag and drop uploading, so if that's a requirement, it won't suit your needs. For what it's worth, here it is (link to live demo at the top):
https://github.com/LPology/Simple-Ajax-Uploader
Okay if i understand it correct, you want to use Drag And Drop fields in differnt parts of your page.
so the short answer is, you would have to add the events to every div, that should have this functionality.since the upload works automatically you just need one file input field
only the dropzones must be copied(but only if you want, more dropzone) and their evens must be adjusted
Ps.: the html part stays the same as in the blog (plus the div with id holder [and holder2 for the second dropzone], which seem to have been omitted)
example:
// tested on Chrome 26+
....
if (tests.dnd) {
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
readfiles(e.dataTransfer.files);
}
//.... other drop spots example need the same events ....
holder2.ondragover = function () { this.className = 'hover'; return false; };
holder2.ondragend = function () { this.className = ''; return false; };
holder2.ondrop = function (e) {
this.className = '';
e.preventDefault();
readfiles(e.dataTransfer.files);
}
} else {
...
}
...
this works, but you could make it niceer using jQuery or so.
i hope it helps
Edit:
If ou want to send files to differnt server-side-scripts you would have to "modify" the function readfiles in te onDrop event
example(possible solution, not very clean):
// tested on Chrome 26+
....
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
readfiles(e.dataTransfer.files, "script_1.php");
}
...
function readfiles(files, posturl) {
...
// now post a new XHR request
if (tests.formdata) {
var xhr = new XMLHttpRequest();
xhr.open('POST', posturl);
...
}
...
Or you could post to the same file, but using a flag to determin on the server from where the file came.
P.s.: you probably know, but still, this Codesnipplets and the one form the blog, need cleanup for production use.
all the best

Can't get value of input type="file"?

I have a <input type="file" id="uploadPicture" value="123">
When I'm using: alert($("#uploadPicture").val());
It alerts an empty dialog.
#BozidarS: FileAPI is supported quite well nowadays and provides a number of useful options.
var file = document.forms['formName']['inputName'].files[0];
//file.name == "photo.png"
//file.type == "image/png"
//file.size == 300821
You can read it, but you can't set it. value="123" will be ignored, so it won't have a value until you click on it and pick a file.
Even then, the value will likely be mangled with something like c:\fakepath\ to keep the details of the user's filesystem private.
You can get it by using document.getElementById();
var fileVal=document.getElementById("some Id");
alert(fileVal.value);
will give the value of file,but it gives with fakepath as follows
c:\fakepath\filename
$('input[type=file]').val()
That'll get you the file selected.
However, you can't set the value yourself.
You can't set the value of a file input in the markup, like you did with value="123".
This example shows that it really works:
http://jsfiddle.net/marcosfromero/7bUba/
array of files
let files = document.getElementById('your_input_id').files
first file
let file = document.getElementById('your_input_id').files[0]
show image onload
const reader = new FileReader()
let files = document.getElementById('your_input_id').files
reader.onload = async (event) => {
document.getElementById('preview').setAttribute('src', event.target.result)
}
reader.readAsDataURL(files[0])
It's old question but just in case someone bump on this tread...
var input = document.getElementById("your_input");
var file = input.value.split("\\");
var fileName = file[file.length-1];
No need for regex, jQuery....
don't give this in file input value="123".
$(document).ready(function(){
var img = $('#uploadPicture').val();
});

Is robust javascript-only upload of file possible

I want a robust way to upload a file. That means that I want to be able to handle interruptions, error and pauses.
So my question is: Is something like the following possible using javascript only on the client.
If so I would like pointers to libraries, tutorials, books or implementations.
If not I would like an explanation to why it's not possible.
Scenario:
Open a large file
Split it into parts
For each part I would like to
Create checksum and append to data
Post data to server (the server would check if data uploaded correctly)
Check a web page on server to see if upload is ok
If yes upload next part if no retry
Assume all posts to server is accompanied by relevant meta data (sessionid and whatnot).
No. You can, through a certain amount of hackery, begin a file upload with AJAX, in which case you'll be able to tell when it's finished uploading. That's it.
JavaScript does not have any direct access to files on the visitor's computer for security reasons. The most you'll be able to see from within your script is the filename.
Firefox 3.5 adds support for DOM progress event monitoring of XMLHttpRequest transfers which allow you to keep track of at least upload status as well as completion and cancellation of uploads.
It's also possible to simulate progress tracking with iframes in clients that don't support this newer XMLHTTPRequest additions.
For an example of script that does just this, take a look at NoSWFUpload. I've been using it succesfully for about few months now.
It's possible in Firefox 3 to open a local file as chosen by a file upload field and read it into a JavaScript variable using the field's files array. That would allow you to do your own chunking, hashing and sending by AJAX.
There is some talk of getting something like this standardised by W3, but for the immediate future no other browser supports this.
Yes. Please look at the following file -
function Upload() {
var self = this;
this.btnUpload;
this.frmUpload;
this.inputFile;
this.divUploadArea;
this.upload = function(event, target) {
event.stopPropagation();
if (!$('.upload-button').length) {
return false;
}
if (!$('.form').length) {
return false;
}
self.btnUpload = target;
self.frmUpload = $(self.btnUpload).parents('form:first');
self.inputFile = $(self.btnUpload).prev('.upload-input');
self.divUploadArea = $(self.btnUpload).next('.uploaded-area');
var target = $(self.frmUpload).attr('target');
var action = $(self.frmUpload).attr('action');
$(self.frmUpload).attr('target', 'upload_target'); //change the form's target to the iframe's id
$(self.frmUpload).attr('action', '/trnUpload/upload'); //change the form's action to the upload iframe function page
$(self.frmUpload).parent("div").prepend(self.iframe);
$('#upload_target').load(function(event){
if (!$("#upload_target").contents().find('.upload-success:first').length) {
$('#upload_target').remove();
return false;
} else if($("#upload_target").contents().find('.upload-success:first') == 'false') {
$('#upload_target').remove();
return false;
}
var fid = $("#upload_target").contents().find('.fid:first').html();
var filename = $("#upload_target").contents().find('.filename:first').html();
var filetype = $("#upload_target").contents().find('.filetype:first').html();
var filesize = $("#upload_target").contents().find('.filesize:first').html();
$(self.frmUpload).attr('target', target); //change the form's target to the iframe's id
$(self.frmUpload).attr('action', action); //change the form's
$('#upload_target').remove();
self.insertUploadLink(fid, filename, filetype, filesize);
});
};
this.iframe = '' +
'false' +
'';
this.insertUploadLink = function (fid, filename, filetype, filesize) {
$('#upload-value').attr('value', fid);
}
}
$(document).ready(event) {
var myupload = new Upload();
myupload.upload(event, event.target);
}
With also using PHP's APC to query the status of how much of the file has been uploaded, you can do a progress bar with a periodical updater (I would use jQuery, which the above class requires also). You can use PHP to output both the periodical results, and the results of the upload in the iframe that is temporarily created.
This is hackish. You will need to spend a lot of time to get it to work. You will need admin access to whatever server you want to run it on so you can install APC. You will also need to setup the HTML form to correspond to the js Upload class. A reference on how to do this can be found here http://www.ultramegatech.com/blog/2008/12/creating-upload-progress-bar-php/

Categories

Resources