e_maxm
e_maxm

Reputation: 3273

Why do browsers present selected files as coming from C:\fakepath\ instead of their true local path?

<input type="file"
  onchange="this.nextElementSibling.textContent = this.value;">
<p>

When I pick a file from the input above, I get a path like this:

C:\fakepath\test.csv

or this (Mozilla):

test.csv

I want the fully qualified local 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?

Upvotes: 324

Views: 641659

Answers (13)

Scott-MEARN-Developer
Scott-MEARN-Developer

Reputation: 392

The best solution for this, I've found, is to use a middleware like Multer. Here's a quick rundown:

  1. npm i multer
  2. Add enctype="multipart/form-data" to your html form.
  3. In your backend dock where you're making your post request, require multer (const multer = require('multer'))
  4. 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.
  5. 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!

Upvotes: 0

I am L
I am L

Reputation: 4662

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.

Upvotes: 8

CodeToLife
CodeToLife

Reputation: 4171

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>

enter image description here you can find the path string at the bottom. It opens stream to file and then deletes it.

Upvotes: -2

Marcos Di Paolo
Marcos Di Paolo

Reputation: 669

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 + ")" });

        }
    }

Upvotes: 2

Shiva Brahma
Shiva Brahma

Reputation: 49

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

Upvotes: -3

chakroun yesser
chakroun yesser

Reputation: 1497

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;
}

Upvotes: 64

Joe Enos
Joe Enos

Reputation: 40431

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.

Upvotes: 217

Sardesh Sharma
Sardesh Sharma

Reputation: 1759

Use

document.getElementById("file-id").files[0].name; 

instead of

document.getElementById('file-id').value

Upvotes: 112

Zernel
Zernel

Reputation: 1547

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

Upvotes: 1

Anand Sharma
Anand Sharma

Reputation: 127

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);

Upvotes: 11

saikiran1043
saikiran1043

Reputation: 409

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

Upvotes: 36

Telefoontoestel
Telefoontoestel

Reputation: 61

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.

Upvotes: 6

jcoder
jcoder

Reputation: 30055

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.

Upvotes: 4

Related Questions