จะแก้ไข C: \ fakepath ได้อย่างไร?


256
<input type="file" id="file-id" name="file_name" onchange="theimage();">

นี่คือปุ่มอัพโหลดของฉัน

<input type="text" name="file_path" id="file-path">

นี่คือช่องข้อความที่ฉันต้องแสดงเส้นทางแบบเต็มของไฟล์

function theimage(){
 var filename = document.getElementById('file-id').value;
 document.getElementById('file-path').value = filename;
 alert(filename);
}

นี่คือ JavaScript ที่แก้ปัญหาของฉัน แต่ในการแจ้งเตือนค่าให้ฉัน

C:\fakepath\test.csv 

และ Mozilla ให้ฉัน:

test.csv

แต่ฉันต้องการท้องถิ่นเส้นทางของไฟล์ที่มีคุณสมบัติครบถ้วน วิธีแก้ปัญหานี้?

หากนี่เป็นเพราะปัญหาด้านความปลอดภัยของเบราว์เซอร์แล้ววิธีอื่นควรทำเช่นไร?


41
นี่เป็นการใช้งานความปลอดภัยของเบราว์เซอร์เบราว์เซอร์ปกป้องคุณจากการเข้าถึงโครงสร้างดิสก์ของคุณ มันอาจช่วยได้ถ้าคุณสามารถอธิบายได้ว่าทำไมคุณถึงต้องการเส้นทางแบบเต็ม
Stuart

1
URL แบบเต็มคุณหมายถึงอะไร ที่อยู่ของไฟล์ที่อัพโหลด?
ก็

4
สำหรับเร็กคอร์ดนั้น IE ให้บิต "fakepath" เท่านั้นเนื่องจากพวกเขาไม่ต้องการเซิร์ฟเวอร์ที่ "คาดหวัง" เส้นทางที่จะแตก มิฉะนั้นเช่นเดียวกับเบราว์เซอร์อื่น ๆ เพื่อความปลอดภัยคุณจะได้รับชื่อไฟล์เท่านั้น (ไม่มีเส้นทาง) ที่สำคัญกว่านั้นถ้าคุณมีเจตนาร้ายฉันไม่สามารถเห็นได้ว่าทำไมการรู้เส้นทางจึงมีประโยชน์
scunliffe

2
browser security issue~ หากมีการใช้งานในเบราว์เซอร์ (อย่างถูกต้อง) ดังนั้นจึงไม่น่าเป็นไปได้สูงที่คุณจะสามารถหลบเลี่ยงมันได้
Ross

13
เอ้ยเลยฉันเก็บไฟล์ทั้งหมดไว้C:\fakepathดังนั้นตอนนี้ทุกคนก็รู้โครงสร้างไดเรกทอรีของฉัน
mbomb007

คำตอบ:


173

เบราว์เซอร์บางตัวมีคุณสมบัติความปลอดภัยที่ป้องกันไม่ให้ JavaScript รู้เส้นทางแบบเต็มของไฟล์ของคุณ มันสมเหตุสมผลแล้วในฐานะลูกค้าคุณไม่ต้องการให้เซิร์ฟเวอร์รู้ระบบไฟล์ของเครื่องของคุณ มันจะดีถ้าเบราว์เซอร์ทั้งหมดทำเช่นนี้


9
หากเบราว์เซอร์ไม่ได้ส่งพา ธ ของไฟล์ในตัวเครื่องไปจะไม่มีวิธีในการค้นหา
Petteri Hietavirta

47
เพียงโพสต์แบบฟอร์ม: เบราว์เซอร์จะดูแลการอัปโหลด เว็บไซต์ของคุณไม่จำเป็นต้องรู้เส้นทางแบบเต็มกลับมาที่ลูกค้า
โฟโต้

2
@ruffp คุณสามารถอัปโหลดด้วยโพสต์ได้ดังนั้นคุณต้องใส่การอัปโหลดในแบบฟอร์มและส่ง ซึ่งจะยังคงใช้การควบคุมการอัปโหลดไฟล์มาตรฐานเพื่อเลือกไฟล์และคุณยังคงไม่จำเป็นต้องใช้ชื่อไฟล์ไคลเอนต์แบบเต็ม
Rupee

6
ฉันสงสัยว่ามีสิ่งใดที่เป็นอันตรายเว็บไซต์ปกติสามารถทำได้กับเครื่องของคุณโดยไม่ต้องมีปลั๊กอินที่เชื่อถือได้เช่น Flash หรือ Java มันเป็นเรื่องของความเป็นส่วนตัวมากกว่า ตัวอย่างเช่นถ้าคุณกำลังอัปโหลดจากเดสก์ทอปของคุณคุณต้องการจะปล่อยให้เซิร์ฟเวอร์ทราบชื่อผู้ใช้ของคุณบนเครื่องของคุณหรือโดเมน ( c:\users\myname\desktopหรือ/Users/myname/Desktop/หรืออะไรก็ตาม) นั่นไม่ใช่สิ่งที่เว็บเซิร์ฟเวอร์มีธุรกิจที่รู้
Joe Enos

8
ความเป็นส่วนตัวมักเกี่ยวข้องกับความปลอดภัยและความเสี่ยงเป็นข้อมูลที่สามารถนำมาใช้กับใครบางคน การโจมตีมักใช้ประโยชน์จากหลาย ๆ ประเด็นเพื่อให้บรรลุเป้าหมาย ทุกคนที่ไม่ตระหนักถึงอันตรายไม่ควรได้รับอนุญาตให้อยู่ใกล้กับรหัสอื่นที่ไม่ใช่ Hello World โดยไม่ต้องมีการอบรมเชิงปฏิบัติการแบบหวาดระแวงเพิ่มเติม
Archimedix

70

ใช้

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

แทน

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

16
ใน Chrome 44.0.2403.125 สิ่งนี้จะให้ชื่อไฟล์แก่คุณเท่านั้น
ช่องว่าง

4
จากนั้นใช้ document.getElementById ("file-id"). files [0] .path ทำงานได้ดีสำหรับฉัน
Loaderon

ขอบคุณ @ Loaderon คุณควรโพสต์สิ่งนี้เป็นคำตอบ!
7geeky

45

ฉันใช้วัตถุ FileReader ในonchangeกิจกรรมอินพุตสำหรับประเภทไฟล์อินพุตของคุณ! ตัวอย่างนี้ใช้ฟังก์ชัน 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;
}

ความคิดใด ๆ ว่าทำไมถึงอย่างนี้ไม่ทำงานบน localhost? แหล่งที่มาจะได้รับการตั้งค่าเป็นsrc = "C: \ fakepath \ filename.jpg"แต่ console.logging องค์ประกอบภาพกล่าวว่า src เป็น dataURL
galki

คำตอบ: การแสดงผล backbone: /
galki

1
คุณไม่ทราบว่าบันทึกรายการนี้ยุ่งยากมากเพียงใด มันเป็นเพชรที่หยาบคายเพียง 12 คะแนนขึ้นไป แต่สมควรได้รับมากกว่านี้ ดีใจที่ฉันมองลงไปอีกเพราะรายการอื่น ๆ ที่มี upvotes ที่สูงกว่ามากไม่ทำงานและ FormData () จะไม่ใช้กลอุบายเพื่อจุดประสงค์ของเรา ทำได้ดี!
user1585204

9
คำถามกำลังขอเส้นทางของไฟล์ไม่ใช่เนื้อหาของไฟล์
เควนติน

@Quentin: ใช่คุณพูดถูก แต่เจตนาที่ชัดเจนของ OP ก็คือสามารถอัพโหลดไฟล์ไปยังเซิร์ฟเวอร์ได้ ดังนั้นวิธีแก้ปัญหานี้จะเป็นประโยชน์อย่างมากกับทุกคนที่มองหาวิธีอัพโหลดไฟล์ไปยังเซิร์ฟเวอร์โดยใช้ JS
user18490

36

หากคุณไปที่ Internet Explorer, เครื่องมือ, ตัวเลือกอินเทอร์เน็ต, ความปลอดภัย, กำหนดเอง, ค้นหา "รวมเส้นทางไดเรกทอรีท้องถิ่นเมื่ออัปโหลดไฟล์ไปยังเซิร์ฟเวอร์" (มันค่อนข้างวิธีลง) และคลิกที่ "เปิดใช้งาน" สิ่งนี้จะได้ผล


2
มีบางอย่างที่คล้ายกับ Chrome หรือไม่
Zaven Zareyan

11

ฉันมีความสุขที่เบราว์เซอร์ใส่ใจที่จะช่วยเราให้รอดพ้นจากสคริปต์ที่ล่วงละเมิดและไม่ชอบ ฉันไม่มีความสุขกับการใส่ IE ลงในเบราว์เซอร์ที่ทำให้การแก้ไขสไตล์แบบง่าย ๆ ดูเหมือนแฮ็คโจมตี!

ฉันใช้ <span> เพื่อแสดงไฟล์อินพุตเพื่อให้ฉันสามารถใช้สไตล์ที่เหมาะสมกับ <div> แทน <input> (อีกครั้งเนื่องจาก IE) ตอนนี้เนื่องจาก IE นี้ต้องการแสดงพา ธ ของผู้ใช้ที่มีค่าซึ่งรับประกันว่าจะทำให้พวกเขาระวังตัวและอยู่ในความวิตกกังวลน้อยที่สุด (ถ้าไม่ทำให้พวกเขากลัว!

อย่างไรก็ตามขอขอบคุณผู้ที่โพสต์คำอธิบายที่นี่: IE Browser Security: การต่อท้าย "fakepath" ไปยังเส้นทางของไฟล์ใน input [type = "file"]ฉันได้รวบรวมผู้ให้บริการรายย่อย ...

โค้ดด้านล่างทำสองสิ่ง - แก้ไขข้อผิดพลาด lte IE8 ที่เหตุการณ์ onChange ไม่เริ่มทำงานจนกว่า onBlur ของฟิลด์อัปโหลดและอัปเดตองค์ประกอบด้วย filepath ที่สะอาดซึ่งจะไม่ทำให้ผู้ใช้กลัว

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

โปรดทราบว่าวิธีนี้ใช้ไม่ได้กับ IE ดังนั้น ฉันแทนที่สิ่งต่อไปนี้: filePath.substring (filePath.lastIndexOf ('\\') + 1, filePath.length)
Bassel Kh

6

ฉันเจอปัญหาเดียวกัน ใน IE8 มันสามารถแก้ไขได้โดยการสร้างอินพุตที่ซ่อนอยู่หลังจากการควบคุมอินพุตไฟล์ เติมสิ่งนี้ด้วยค่าของพี่น้องก่อนหน้านี้ ใน IE9 นี้ได้รับการแก้ไขเช่นกัน

เหตุผลที่ฉันต้องการทำความรู้จักกับเส้นทางแบบเต็มคือการสร้างภาพตัวอย่างจาวาสคริปต์ก่อนที่จะอัปโหลด ตอนนี้ฉันต้องอัปโหลดไฟล์เพื่อสร้างภาพตัวอย่างของภาพที่เลือก


1
หากมีคนต้องการเห็นภาพก่อนที่จะอัพโหลดพวกเขาสามารถดูได้ในคอมพิวเตอร์ของพวกเขา
mbomb007

4

หากคุณต้องการส่งพา ธ แบบเต็มของไฟล์อัพเดลจริง ๆ คุณอาจต้องใช้แอปเพล็ต java ที่เซ็นชื่อแล้วเนื่องจากไม่มีวิธีรับข้อมูลนี้หากเบราว์เซอร์ไม่ส่ง


วิธีการพา ธ แบบเต็มพา ธ ดั้งเดิม <input type = "file" accept = ". jpeg, .jpg, .png">. ฉันได้รับเส้นทางปลอม, วิธีการ reslove
Govind Sharma


1

ใช้โปรแกรมอ่านไฟล์:

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

        }
    }

-1

ที่นั่นในกรณีของฉันฉันใช้สภาพแวดล้อมการพัฒนา asp.net ดังนั้นฉันจึงต้องการอัปโหลดข้อมูลเหล่านั้นในคำขอ asynchronus ajax ใน [webMethod] คุณไม่สามารถจับตัวอัพโหลดไฟล์ได้เนื่องจากมันไม่ใช่องค์ประกอบที่คงที่ดังนั้นฉันต้อง ทำให้ผลประกอบการสำหรับการแก้ปัญหาดังกล่าวโดยการแก้ไขเส้นทางกว่าแปลงภาพที่ต้องการเป็นไบต์เพื่อบันทึกไว้ใน DB

นี่คือฟังก์ชั่นจาวาสคริปต์ของฉันหวังว่าจะช่วยให้คุณ:

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

-3

การใช้คำตอบของ Sardesh Sharma:

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

สำหรับเส้นทางเต็ม


สิ่งนี้จะกลับundefinedมาให้ฉันใน FireFox 75.0 ไม่pathอยู่จริง? คุณมีเอกสารอ้างอิงเกี่ยวกับมันหรือไม่?
Jose Manuel Abarca Rodríguez

1
Hi! ฉันโพสต์คำตอบนี้หลังจากพยายามแก้ปัญหาด้วยตนเองและประสบความสำเร็จในการใช้เส้นทาง ฉันจำไม่ได้ว่าฉันพยายามทำโครงการอะไร แต่ฉันใช้ Google Chrome อยู่เสมอบางทีโซลูชันนี้เหมาะสำหรับเบราว์เซอร์นั้นเท่านั้น และมันอาจจะล้าสมัยเนื่องจากการอัพเดทเบราว์เซอร์ ขออภัยที่ไม่สามารถช่วยเหลือเพิ่มเติม: /
Loaderon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.