为什么浏览器将所选文件显示为来自 C:\fakepath\ 而不是其真实的本地路径?

发布于 2024-11-03 11:39:32 字数 426 浏览 0 评论 0原文

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

当我从上面的输入中选择一个文件时,我得到如下路径:

C:\fakepath\test.csv

或这个(Mozilla):

测试.csv

我想要完全限定的本地文件路径。如何解决这个问题?

如果这是由于浏览器安全问题造成的,那么替代方法应该是什么?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

挖个坑埋了你 2024-11-10 11:39:32

某些浏览器具有安全功能,可防止 JavaScript 了解文件的本地完整路径。这是有道理的 - 作为客户端,您不希望服务器知道您本地计算机的文件系统。如果所有浏览器都这样做就好了。

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.

执手闯天涯 2024-11-10 11:39:32

使用

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

而不是

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

Use

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

instead of

document.getElementById('file-id').value
坏尐絯℡ 2024-11-10 11:39:32

我在您的输入文件类型的输入 onchange 事件上使用对象 FileReader!此示例使用 readAsDataURL 函数,因此您应该有一个标签。 FileReader 对象还具有 readAsBinaryString 来获取二进制数据,稍后可用于在服务器上创建相同的文件

示例:

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

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;
}
预谋 2024-11-10 11:39:32

如果您转到 Internet Explorer、工具、Internet 选项、安全、自定义,找到“将文件上传到服务器时包括本地目录路径”(这是相当低的方式),然后单击“启用”。这会起作用

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

想你的星星会说话 2024-11-10 11:39:32

我很高兴浏览器愿意将我们从侵入性脚本等中拯救出来。我对 IE 在浏览器中添加一些东西让简单的样式修复看起来像是黑客攻击感到不满意!

我用过<跨度>表示文件输入,以便我可以将适当的样式应用于 <分区>而不是 <输入> (再次,因为 IE)。现在,由于这个 IE 希望向用户展示一条具有一定值的路径,该值保证让他们保持警惕,并且至少不担心(如果没有完全吓跑他们?!)... 更多 IE-废话!

无论如何,感谢那些在这里发布解释的人: IE 浏览器安全性:将“fakepath”附加到输入[type="file"]中的文件路径,我已经整理了一个较小的修复程序...

下面的代码做了两件事- 它修复了一个 lte IE8 错误,其中 onChange 事件在上传字段的 onBlur 之前不会触发,并且使用干净的文件路径更新元素,不会吓到用户。

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

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);
芯好空 2024-11-10 11:39:32

在像 Electron 这样基于 Chrome/Chromium 的应用程序上,你可以只使用 target.files:

(我在这个例子中使用 React JS)

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} />
)

我上面所说的 File 对象 看起来像这样:

{
  fullName: "C:\Users\myname\Downloads\somefile.ext"
  lastModified: 1593086858659
  lastModifiedDate: (the date)
  name: "somefile.ext"
  size: 10235546
  type: ""
  webkitRelativePath: ""
}

那么你如果你想获取路径,只需获取fullName即可。

请注意,这仅适用于 chrome/chromium 浏览器,因此如果您不必支持其他浏览器(例如您正在构建电子项目),则可以使用它。

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.

兮子 2024-11-10 11:39:32

我遇到了同样的问题。在 IE8 中,可以通过在文件输入控件之后创建隐藏输入来解决此问题。用它的前一个同级的值填充它。在 IE9 中,这个问题也得到了修复。

我想要了解完整路径的原因是在上传之前创建一个 javascript 图像预览。现在我必须上传文件以创建所选图像的预览。

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.

岛徒 2024-11-10 11:39:32

如果您确实需要发送上传文件的完整路径,那么您可能必须使用诸如签名的 java 小程序之类的东西,因为如果浏览器不发送该信息,则没有任何方法可以获取该信息。

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.

岁月打碎记忆 2024-11-10 11:39:32

使用文件阅读器:

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

        }
    }

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

        }
    }
三月梨花 2024-11-10 11:39:32

似乎你无法通过js找到本地主机中的完整路径,但你可以隐藏fakepath以仅显示文件名。 使用 jQuery 获取文件输入的选定文件名,不带路径

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

苏辞 2024-11-10 11:39:32

我发现最好的解决方案是使用像 Multer 这样的中间件。以下是一个快速概述:

  1. npm i multer
  2. enctype="multipart/form-data" 添加到您的 html 表单。
  3. 在您发出发布请求的后端 Dock 中,需要 multer (const multer = require('multer'))
  4. 在同一个 Dock 中,设置您的上传目的地:const upload = multer ({dest:'uploas/'})。这将自动创建一个名为“uploads”的本地文件夹,您的文件将添加到其中。我包含的代码向您展示了如何上传到本地磁盘存储。如果您使用云存储(例如 AWS、Azure、Cloudinary 等),您可以查看 Multer 文档以了解如何管理它。不过,没有太多额外的步骤。
  5. 在您的发布请求中,添加“upload.single”(对于一个文件)或“upload.array”(对于多个文件),如下所示:
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'
});

req.file 将具有可在发布请求中使用的完整路径名。有关更多信息,请查看 Multer 文档:

https://www.npmjs.com/package/multer< /a>

我希望这有帮助!

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!

少年亿悲伤 2024-11-10 11:39:32

您将能够至少在计算机上获得临时创建的文件路径副本。这里唯一的条件是您的输入元素应该位于表单内
您还需要做的就是以属性 enctype 的形式放入,例如:

<form id="formid" enctype="multipart/form-data" method="post" action="{{url('/add_a_note' )}}">...</form>

在此处输入图像描述
您可以在底部找到路径字符串。
它打开文件流,然后将其删除。

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.

醉生梦死 2024-11-10 11:39:32

你好,就我而言,我使用的是asp.net开发环境,所以我想在异步ajax请求中上传这些数据,在[webMethod]中你无法捕获文件上传器,因为它不是静态元素,
所以我必须通过修复路径来解决这种解决方案,而不是将所需的图像转换为字节以将其保存在数据库中。

这是我的 javascript 函数,
希望它对您有帮助:

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

这里仅用于测试:

 $(document).ready(function () {
             FixPath("hakounaMatata:/7ekmaTa3mahaLaziz/FakePath/EnsaLmadiLiYghiz");
         });
// this will give you : ~/EnsaLmadiLiYghiz

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文