283
<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?

Michał Perłakowski
  • 70,955
  • 24
  • 137
  • 155
e_maxm
  • 2,855
  • 2
  • 13
  • 3
  • 46
    This is the security implementation of the browser - the browser is protecting you from accessing your disk structure. It might help if you can explain why you want the full path. – Stuart Jan 31 '11 at 13:51
  • 1
    What do you mean by **full url** ? Address of uploaded file ? – gor Jan 31 '11 at 13:51
  • @gor, yes. Say my file in '/home/..../.../mydir/test.csv' – e_maxm Jan 31 '11 at 13:53
  • 4
    For the record, IE only gives the "fakepath" bit because they didn't want servers that were "expecting" a path to break. Otherwise just like other browsers for security reasons you will only get the filename (no path). More importantly, unless you have malicious intentions I can't see why knowing the path provides anything useful. – scunliffe Jan 31 '11 at 13:56
  • @scunliff, I have upload button on a pop. Using this JS I was trying to fill pass the full url to the "hidden field". I was catching the hidden fields in my handler. – e_maxm Jan 31 '11 at 13:59
  • 2
    `browser security issue` ~ if its implemented in the browser (rightly so) then it's highly unlikely you can circumvent it – Ross Jan 31 '11 at 14:22
  • 1
    @e_maxm What server language are you using (C#, PHP, etc.)? Maybe we can help out with an example of how to handle the uploaded file. – Joe Enos Jan 31 '11 at 14:23
  • 1
    @e_maxm - what were you going to do with the file/path name in the hidden field? it is still of no use on the server. That said, JavaScript will not let you copy the filename from the file field for **security reasons** so this won't work anyway. – scunliffe Jan 31 '11 at 15:19
  • 1
    I can understanding them not wanting to show the full URL for security reasons but making up c:\fakepath\ seems pretty unprofessional... – theycallmemorty May 15 '14 at 14:25
  • @theycallmemorty: official quote: `This "fakepath" requirement is a sad accident of history`, some more in-depth info and references in [this linked answer](http://stackoverflow.com/a/20537822/588079) (by me), which also covers the OP's question above. – GitaarLAB May 21 '15 at 06:59
  • 22
    Gosh darnit, I keep all of my files in `C:\fakepath`, so now everyone knows my directory structure. – mbomb007 Jul 06 '18 at 15:01

12 Answers12

185

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.

Michał Perłakowski
  • 70,955
  • 24
  • 137
  • 155
Joe Enos
  • 36,707
  • 11
  • 72
  • 128
  • 1
    Then what is the alternate way to know the full url? – e_maxm Jan 31 '11 at 13:52
  • 9
    If the browser does not send the local file path, there is no way to find it out. – Petteri H Jan 31 '11 at 13:53
  • 51
    Just post the form: the browser will take care of the upload. Your web site doesn't need to know the full path back on the client. – Rup Jan 31 '11 at 14:09
  • And what about uploading with ajax (DWR controller)? I want to be able to upload many files before sending the form (like in gmail in fact) – рüффп Dec 13 '11 at 15:36
  • 2
    @ruffp You can only upload with a post so you need to put the upload in a form and submit it. That will still use a standard file upload control to choose the file and you still won't need the full client filename. – Rup Dec 26 '11 at 01:08
  • Thanks Rup, finally I found there was a problem with the DWR version 2.0.8 where utils.js was not fully implemented. Using the DWR 3.0.rc2 fixed my problem. – рüффп Jan 01 '12 at 13:38
  • what's the security problem? Even if javascript knows the absolute file path in local disk, but javascrit can't read & write local file. And Even if Servers know client file path, what damage can it do to clients? anyone can explain it to me? Thx. – hiway Jun 21 '13 at 05:25
  • 6
    I doubt there's anything malicious a normal website can do to your local machine without some kind of trusted plugin like Flash or Java. It's more of a privacy thing. For example, if you're uploading from your desktop, you'd be letting the server know your username on your local machine or domain (`c:\users\myname\desktop` or `/Users/myname/Desktop/` or whatever). That's not something a webserver has any business knowing. – Joe Enos Jun 21 '13 at 15:46
  • 9
    Privacy almost always relates to security and vulnerability as information can be used against someone. Attacks frequently exploit multiple issues to achieve their goals. Anyone not recognizing the dangers should not be allowed near code other than Hello World without additional how-to-be-paranoid workshops. – Arc Sep 09 '13 at 12:34
  • @e_maxm, You can put a condition `if(filePath.match(/fakepath/)) {` like $Anand Sharma has provided in his answer. I was also facing same issue and gone with this condition. Doing other settings from `Internet Options` is only know for tech people and not for other people. So better to provide condition and replace `C:\fakepath`. And I also upvoted your question :) for good question. – NullPointer Sep 19 '13 at 10:42
  • Why/how is this actually adding security? JavaScript shouldn't be able to affect the end-users computer's file system, given a file path or not. There are known paths with much higher security risks than anything the client would voluntarily upload, for example the Windows directory is always at C:\Windows, users will be under C:\Users, who cares? How does that information help an attacker in any way (it doesn't)? And why must chrome hide something from the client themselves to do this? – Deji Mar 30 '16 at 13:30
  • 1
    @Deji As I indicated in a comment, it's more about privacy than it is about specific protection from a single attack. Uploaded file paths often will include the username of the user, which is information that the web server wouldn't have otherwise known. Depending on what's being uploaded and why, this might be enough for a malicious person to do bad things that they wouldn't have been able to with just the file. – Joe Enos Mar 30 '16 at 15:08
  • @JoeEnos ... like? – Deji Mar 30 '16 at 15:54
  • 1
    @Deji A photo manipulation site sees a photo of a person, and along with their username, uses this photo to create a fake social media account to scam either the uploader or one of their friends. I'm sure people who do bad things for a living can give you more examples, but even without a common example, it's simply none of the server's business what my local directory structure or local username is. – Joe Enos Mar 30 '16 at 16:23
  • @JoeEnos Many times the full path includes a directory that is .../Users/username/Documents/.... poof now the server (run by some hacker) knows the name of a valid user on your system. One less thing to guess when trying to hack in ... or if someone succeeds in playing man in the middle against you, they found out your user name. (which for 99% of home computers is also the administrator account) – Gus Jul 05 '16 at 22:00
  • As an additional example nobody has mentioned, maybe I'm working on a secret project, could even be a competitor to the very site I'm using. I don't want to fear exposing my folder names every time I'm uploading a file. (Not to mention that exposing the user name is a HUGE privacy blunder; what if I'm trying to stay anonymous, but using a real name for my computer account?) Forget hacking, it's about leaking information. – Andrey Tarantsov Oct 12 '16 at 13:26
  • @Archimedix: I'm interested in taking that "how-to-be-paranoid" workshop. **Which one do you recommend?** Serious question, I've a rather seasoned developer and if there's anything that I've learned, it is that we cannot be paranoid enough. – dotancohen Oct 18 '17 at 08:19
  • @dotancohen in this scenario, one could imagine a porn consumer with a very unique name inferable from the user name saving some video clip to C:\Users\JEdgarHooper\Videos\Porn\AgentsDoingIt.mp4 and uploading it to virustotal.com, which saves the file path and blackmails Hooper. In social media, think about why you post something. What does that post reveal about you? Maybe that you’re working for the CIA, male, like weapons and cat videos, are homophobic (keep saying "That‘s so gay")... a starting point for social engineering. Just challenge yourself to see how things can be used against you. – Arc Oct 19 '17 at 05:42
  • @Archimedix: I agree that revealing the path is revealing too much sensitive information, that was never in dispute. I'm asking about your previous comment about some hypothetical workshop which might introduce me to more things to be paranoid about! – dotancohen Oct 19 '17 at 10:36
  • @dotancohen that was the point I tried to make, reading closely, the _world_ and your very behavior is your workshop (though there is a workshop about practical paranoia relating to IT security, along with a few books, not advertising here). Just look as far as your fingertips, but if you have exhausted your personal self already and still do not feel paranoid enough, subscribe to any news, not just IT. The git bomb was just rediscovered, existed on GitHub since at least 2014 in hiding, but similar bombs (ZIP, fork) are much older, which hasn't stopped git devs from making the same mistakes. – Arc Oct 19 '17 at 19:21
  • @dotancohen CompuServe was giving you 10 hours of Internet a month for free, any additional usage was charged but you could open the billing information page within CompuServe (which was always free) whilst surfing the open waters to surf forever. Was it a PR stunt? Who knows. WPA2 KRACKed? No, it is a feature to resend data you might have missed, oops, forgot that you should never reuse counters in crypto. This unsuspecting burglar was not too paranoid: http://www.dailymail.co.uk/news/article-2667413/Burglar-busted-stopping-check-FACEBOOK-victims-computer-forgetting-log-out.html – Arc Oct 19 '17 at 19:37
85

Use

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

instead of

document.getElementById('file-id').value
Manwal
  • 22,117
  • 10
  • 57
  • 89
Sardesh Sharma
  • 1,473
  • 10
  • 13
53

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;
}
Komal12
  • 3,119
  • 4
  • 13
  • 25
chakroun yesser
  • 1,221
  • 1
  • 10
  • 17
  • any idea why even this isn't working on localhost? the source gets set as *src="C:\fakepath\filename.jpg"* but console.logging the image element says the src is a dataURL – galki Aug 18 '15 at 06:51
  • answer: backbone rerendering :/ – galki Aug 18 '15 at 07:17
  • 1
    You have no idea how much frustration this entry saved. It's a diamond in the rough ... only 12 up votes but deserving of much more. Glad I looked further down because the other entries with much higher upvotes weren't working and also FormData() won't do the trick for our purposes. Well Done! – user1585204 Jun 09 '17 at 14:04
  • 10
    The question is asking for the file **path** not the file content. – Quentin Aug 29 '17 at 10:47
  • @Quentin: yes you are right, but cleary the intent of the OP is to be able to somehow maybe upload the file to the server. Thus this solution would work is certainly very helpful to all people who look for a way of uploading files to a server using JS. – user18490 Sep 22 '17 at 18:33
  • tried to implement this for a local video ended up crashing my computer :D – Ali Akber Faiz Sep 26 '18 at 07:45
35

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

saikiran1043
  • 399
  • 4
  • 2
11

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);
Anand Sharma
  • 127
  • 1
  • 3
  • Please note that this doesn't work on IE, hence; I replaced the following : filePath.substring(filePath.lastIndexOf('\\')+ 1 , filePath.length) – Bassel Kh Sep 03 '17 at 07:28
6

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.

4

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.

jcoder
  • 28,098
  • 16
  • 76
  • 120
2

Why don't you 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.

I am L
  • 2,336
  • 2
  • 19
  • 35
  • 3
    If I run your example on https://jscomplete.com/playground in Firefox (use `ReactDOM.render(, mountNode);`), I get an object whose attributes are `lastModified`, `name`, `size`, `type`, and `webkitRelativePath`. Indeed, as others have remarked, being able to get the complete path would in general be a security/privacy issue. So you must have done something else to achieve the result above. – fuglede Sep 30 '20 at 11:20
  • Yes, it would be a security bug if you could get the unredacted file path. – EricLaw Dec 10 '20 at 17:36
1

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

Community
  • 1
  • 1
Zernel
  • 1,387
  • 2
  • 13
  • 25
1

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

        }
    }
Marcos Di Paolo
  • 300
  • 2
  • 14
-1

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.

CodeToLife
  • 2,276
  • 2
  • 28
  • 21
  • The question is asking for "the **local** fully qualified file path". Uploading a copy to the server then getting the path to where it was uploaded to is very different. – Quentin May 09 '21 at 13:21
  • @Quentin Its very simple...Because actually Im not a stackoverflower in full meaning of the word )). First of all writing for myself in future. – CodeToLife May 15 '21 at 11:03
-3

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