Không thể mở tệp cục bộ - Chrome: Không được phép tải tài nguyên cục bộ


103

Trình duyệt thử nghiệm: Phiên bản Chrome: 52.0.2743.116

Nó là một javascript đơn giản để mở một tệp hình ảnh từ cục bộ như 'C: \ 002.jpg'

function run(){

   var URL = "file:///C:\002.jpg";

   window.open(URL, null);

}
run();

Đây là mã mẫu của tôi. https://fiddle.jshell.net/q326vLya/3/

Xin vui lòng cho tôi bất kỳ gợi ý phù hợp.


sử dụng <input type=file>để có được quyền truy cập vào reources địa phương
dandavis

Câu trả lời:


64

Biết đây là loại cũ, nhưng thấy nhiều câu hỏi thế này ...

Chúng tôi sử dụng Chrome rất nhiều trong lớp học và bắt buộc phải làm việc với các tệp cục bộ.

Những gì chúng tôi đã và đang sử dụng là "Máy chủ web cho Chrome". Bạn khởi động nó lên, chọn thư mục muốn làm việc và đi đến URL (như 127.0.0.1:port bạn đã chọn)

Nó là một máy chủ đơn giản và không thể sử dụng PHP nhưng đối với công việc đơn giản, có thể là giải pháp của bạn:

https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb


1
Woody: cảm ơn rất nhiều! Cách tiếp cận này đã giúp tôi. Tôi chạy Tomcat cục bộ + một nhóm AWS S3 cục bộ trên Windows 10. Giờ đây, tôi có thể chuyển đổi giữa máy chủ AWS trực tiếp và máy chủ cục bộ. Chúc mừng. Q
user1723453

20

Được rồi mọi người, tôi hoàn toàn hiểu lý do bảo mật đằng sau thông báo lỗi này, nhưng đôi khi, chúng tôi cần một giải pháp thay thế ... và đây là của tôi. Nó sử dụng ASP.Net (thay vì JavaScript, câu hỏi này dựa trên) nhưng hy vọng nó sẽ hữu ích cho ai đó.

Ứng dụng nội bộ của chúng tôi có một trang web nơi người dùng có thể tạo danh sách các phím tắt cho các tệp hữu ích trải khắp mạng của chúng tôi. Khi họ nhấp vào một trong các phím tắt này, chúng tôi muốn mở các tệp này ... nhưng tất nhiên, lỗi của Chrome ngăn cản điều này.

nhập mô tả hình ảnh ở đây

Trang web này sử dụng AngularJS 1.x để liệt kê các phím tắt khác nhau.

Ban đầu, trang web của tôi đang cố gắng tạo trực tiếp một <a href..>phần tử trỏ đến các tệp, nhưng điều này đã tạo ra Not allowed to load local resourcelỗi "" khi người dùng nhấp vào một trong các liên kết này.

<div ng-repeat='sc in listOfShortcuts' id="{{sc.ShtCut_ID}}" class="cssOneShortcutRecord" >
    <div class="cssShortcutIcon">
        <img ng-src="{{ GetIconName(sc.ShtCut_PathFilename); }}">
    </div>
    <div class="cssShortcutName">
        <a ng-href="{{ sc.ShtCut_PathFilename }}" ng-attr-title="{{sc.ShtCut_Tooltip}}" target="_blank" >{{ sc.ShtCut_Name }}</a>
    </div>
</div>

Giải pháp là thay thế các <a href..>phần tử đó bằng mã này, để gọi một hàm trong bộ điều khiển Angular của tôi ...

<div ng-click="OpenAnExternalFile(sc.ShtCut_PathFilename);" >
    {{ sc.ShtCut_Name }}
</div>

Bản thân chức năng này rất đơn giản ...

$scope.OpenAnExternalFile = function (filename) {
    //
    //  Open an external file (i.e. a file which ISN'T in our IIS folder)
    //  To do this, we get an ASP.Net Handler to manually load the file, 
    //  then return it's contents in a Response.
    //
    var URL = '/Handlers/DownloadExternalFile.ashx?filename=' + encodeURIComponent(filename);
    window.open(URL);
}

Và trong dự án ASP.Net của tôi, tôi đã thêm một tệp Xử lý có tên DownloadExternalFile.aspxchứa mã này:

namespace MikesProject.Handlers
{
    /// <summary>
    /// Summary description for DownloadExternalFile
    /// </summary>
    public class DownloadExternalFile : IHttpHandler
    {
        //  We can't directly open a network file using Javascript, eg
        //      window.open("\\SomeNetworkPath\ExcelFile\MikesExcelFile.xls");
        //
        //  Instead, we need to get Javascript to call this groovy helper class which loads such a file, then sends it to the stream.  
        //      window.open("/Handlers/DownloadExternalFile.ashx?filename=//SomeNetworkPath/ExcelFile/MikesExcelFile.xls");
        //
        public void ProcessRequest(HttpContext context)
        {
            string pathAndFilename = context.Request["filename"];               //  eg  "\\SomeNetworkPath\ExcelFile\MikesExcelFile.xls"
            string filename = System.IO.Path.GetFileName(pathAndFilename);      //  eg  "MikesExcelFile.xls"

            context.Response.ClearContent();

            WebClient webClient = new WebClient();
            using (Stream stream = webClient.OpenRead(pathAndFilename))
            {
                // Process image...
                byte[] data1 = new byte[stream.Length];
                stream.Read(data1, 0, data1.Length);

                context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", filename));
                context.Response.BinaryWrite(data1);

                context.Response.Flush();
                context.Response.SuppressContent = true;
                context.ApplicationInstance.CompleteRequest();
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

Và đó là nó.

Bây giờ, khi người dùng nhấp vào một trong các liên kết Phím tắt của tôi, nó sẽ gọi OpenAnExternalFilehàm mở tệp .ashx này, chuyển cho nó đường dẫn + tên tệp của tệp mà chúng ta muốn mở.

Mã Xử lý này tải tệp, sau đó chuyển nội dung của tệp trở lại trong phản hồi HTTP.

Và, công việc đã hoàn thành, trang web sẽ mở tệp bên ngoài.

Phù! Một lần nữa - có một lý do tại sao Chrome ném Not allowed to load local resourcesngoại lệ "" này, vì vậy hãy cẩn thận với điều này ... nhưng tôi đăng mã này chỉ để chứng minh rằng đây là một cách khá đơn giản để giải quyết hạn chế này.

Chỉ một nhận xét cuối cùng: câu hỏi ban đầu muốn mở tệp " C:\002.jpg". Bạn không thể làm điều này. Trang web của bạn sẽ nằm trên một máy chủ (với ổ C: riêng của nó) và không có quyền truy cập trực tiếp vào ổ C: của chính người dùng của bạn. Vì vậy, tốt nhất bạn có thể làm là sử dụng mã như của tôi để truy cập các tệp ở đâu đó trên ổ đĩa mạng.


Nghe có vẻ tốt, nhưng làm cách nào để bạn xử lý ủy quyền (quyền đọc)? Điều gì xảy ra nếu không phải tất cả người dùng đều được phép xem một tệp nhất định? Bạn có cần thực hiện việc đọc với tên của người dùng yêu cầu không?
Timi

Tại sao bạn sử dụng webclient để mở tệp cục bộ? Và đối với tôi, nó cố gắng mở C: \ SomeNetworkPath \ ...
Kev

Nếu chúng ta không sử dụng góc, nó vẫn có thể?
Ahmad.Tr

Đây là một câu trả lời hữu ích nhưng nó sẽ ảnh hưởng rất nhiều đến thời gian tải của trang web nếu bạn có hàng trăm bức ảnh được hiển thị và tải xuống như thế này thông qua tay cầm ashx này.
Jamshaid Kamran

17

Chrome đặc biệt chặn quyền truy cập tệp cục bộ theo cách này vì lý do bảo mật.

Dưới đây là một giải pháp để bật cờ trong Chrome (và mở hệ thống của bạn trước các lỗ hổng bảo mật):

c: \ Program Files (x86) \ google \ chrome \ Application \ chrome.exe --allow-file-access-from-files


4
Tôi đã thử làm theo giải pháp "c: \ path \ chrome.exe" -allow-file-access-from-files nhưng tôi không thể mở được. Vui lòng kiểm tra trang web này fiddle.jshell.net/q326vLya/3 . Tôi đang làm gì sai?
KBH

6
Trên GoogleChrome 66, nó không hoạt động. Chrome bắt đầu với cờ đó, nhưng nó vẫn hiển thị rằng có thể mở tệp cục bộ.
Radon8472

16

1) Mở thiết bị đầu cuối của bạn và nhập

npm install -g http-server

2) Đi tới thư mục gốc mà bạn muốn cung cấp tệp cho mình và nhập:

http-server ./

3) Đọc đầu ra của thiết bị đầu cuối, một cái gì đó http://localhost:8080sẽ xuất hiện.

Tất cả mọi thứ trên đó sẽ được phép có. Thí dụ:

background: url('http://localhost:8080/waw.png');


http-server hiện có sự cố gây ra lỗi - bạn có thể hạ cấp nó xuống 0.9 để khắc phục - xem stackoverflow.com/questions/56364464/…
Brian Burns

Đây là câu trả lời đơn giản nhất đối với tôi. Đã hoạt động 100%. Cảm ơn!
robrecord

9

Có một cách giải quyết bằng cách sử dụng Máy chủ web cho Chrome .
Đây là các bước:

  1. Thêm Tiện ích mở rộng vào chrome.
  2. Chọn thư mục (C: \ images) và khởi chạy máy chủ trên cổng mong muốn của bạn.

Bây giờ dễ dàng truy cập tệp cục bộ của bạn:

function run(){
   // 8887 is the port number you have launched your serve
   var URL = "http://127.0.0.1:8887/002.jpg";

   window.open(URL, null);

}
run();

Tái bút: Bạn có thể cần chọn tùy chọn Tiêu đề CORS từ cài đặt nâng cao trong trường hợp bạn gặp bất kỳ lỗi truy cập nguồn gốc chéo nào.


6

Bạn sẽ không thể tải hình ảnh bên ngoài thư mục dự án hoặc từ thư mục cấp người dùng, do đó, "không thể truy cập cảnh báo tài nguyên cục bộ".

Nhưng nếu bạn đặt tệp trong thư mục gốc của dự án như trong {rootFolder}\Content\my-image.jpgvà tham chiếu nó như vậy:

<img src="/Content/my-image.jpg" />

5

Vấn đề này xảy ra khi tôi đang sử dụng PHP làm ngôn ngữ phía máy chủ và công việc xung quanh là tạo bao phủ base64 cho hình ảnh của tôi trước khi gửi kết quả đến máy khách

$path = 'E:/pat/rwanda.png';
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);

Tôi nghĩ có thể cho ai đó ý tưởng để tạo ra tác phẩm của riêng mình

Cảm ơn


2

Google Chrome không cho phép tải các tài nguyên cục bộ vì tính bảo mật. Chrome cần có url http. Internet Explorer và Edge cho phép tải tài nguyên cục bộ, nhưng Safari, Chrome và Firefox không cho phép tải tài nguyên cục bộ.

Đi tới vị trí tệp và khởi động Máy chủ Python từ đó.

python -m SimpleHttpServer

sau đó đặt url đó vào chức năng:

function run(){
var URL = "http://172.271.1.20:8000/" /* http://0.0.0.0:8000/ or http://127.0.0.1:8000/; */
window.open(URL, null);
}

2

Nếu bạn đã cài đặt php - bạn có thể sử dụng máy chủ tích hợp sẵn. Chỉ cần mở mục tiêu dir với các tệp và chạy

php -S localhost:8001

1

Nếu bạn có thể làm điều này, nó sẽ đại diện cho một vấn đề bảo mật lớn, vì bạn có thể truy cập hệ thống tệp của mình và có khả năng hành động trên dữ liệu có sẵn ở đó ... May mắn thay, bạn không thể làm những gì bạn đang cố gắng làm.

Nếu bạn cần truy cập tài nguyên cục bộ, bạn có thể thử khởi động máy chủ web trên máy của mình và trong trường hợp này, phương pháp của bạn sẽ hoạt động. Có thể có các cách giải quyết khác, chẳng hạn như hành động trên cài đặt Chrome, nhưng tôi luôn thích cách gọn gàng hơn, cài đặt một máy chủ web cục bộ, có thể trên một cổng khác (không, không quá khó!).

Xem thêm:


lý do vì quy tắc mang tính xã hội nhiều hơn là kỹ thuật; trình duyệt thực hiện rất tốt việc ngăn chặn truy cập có chương trình vào các tài nguyên ngoài miền (ví dụ: tập lệnh SOP, CDN, thẻ IMG liên kết sâu, v.v.), nhưng nó khiến mọi người không thấy nội dung cục bộ của họ trong cửa sổ trình duyệt, ngay cả khi script không thể biết nó đang hiển thị những gì ...
dandavis

1
@dandavis vâng, bạn nói đúng, tôi vẫn tin rằng có thể tốt để ngăn điều này xảy ra. Ngoài lỗi trong một số triển khai (nếu bạn không thể mở tài nguyên cục bộ, có lẽ bạn sẽ an toàn hơn), có thể có một số trường hợp cụ thể mà người khác đang nhìn vào màn hình của bạn (ứng dụng chia sẻ màn hình hoặc đơn giản là sau lưng bạn trong văn phòng của bạn ) và bạn không muốn hình ảnh của mình (có thể là Thẻ tín dụng hoặc hình ảnh riêng tư) có thể được mở chỉ bằng cách truy cập một số trang web có thể đoán vị trí trên hệ thống tệp cục bộ của bạn ...
Prak

1

Bạn chỉ cần thay thế tất cả các đường dẫn mạng hình ảnh thành chuỗi byte trong chuỗi HTML được mã hóa được lưu trữ. Đối với điều này, bạn yêu cầu HtmlAgilityPack để chuyển đổi chuỗi Html thành tài liệu Html. https://www.nuget.org/packages/HtmlAgilityPack

Tìm đoạn mã dưới đây để chuyển đổi từng đường dẫn mạng src (hoặc đường dẫn cục bộ) thành đường dẫn byte. Nó chắc chắn sẽ hiển thị tất cả các hình ảnh có đường dẫn mạng (hoặc đường dẫn cục bộ) trong IE, chrome và firefox.

string encodedHtmlString = Emailmodel.DtEmailFields.Rows[0]["Body"].ToString();

// Decode the encoded string.
StringWriter myWriter = new StringWriter();
HttpUtility.HtmlDecode(encodedHtmlString, myWriter);
string DecodedHtmlString = myWriter.ToString();

//find and replace each img src with byte string
HtmlDocument document = new HtmlDocument();
document.LoadHtml(DecodedHtmlString);
document.DocumentNode.Descendants("img")
    .Where(e =>
    {
        string src = e.GetAttributeValue("src", null) ?? "";
        return !string.IsNullOrEmpty(src);//&& src.StartsWith("data:image");
    })
    .ToList()
    .ForEach(x =>
        {
        string currentSrcValue = x.GetAttributeValue("src", null);                                
        string filePath = Path.GetDirectoryName(currentSrcValue) + "\\";
        string filename = Path.GetFileName(currentSrcValue);
        string contenttype = "image/" + Path.GetExtension(filename).Replace(".", "");
        FileStream fs = new FileStream(filePath + filename, FileMode.Open, FileAccess.Read);
        BinaryReader br = new BinaryReader(fs);
        Byte[] bytes = br.ReadBytes((Int32)fs.Length);
        br.Close();
        fs.Close();
        x.SetAttributeValue("src", "data:" + contenttype + ";base64," + Convert.ToBase64String(bytes));                                
    });

string result = document.DocumentNode.OuterHtml;
//Encode HTML string
string myEncodedString = HttpUtility.HtmlEncode(result);

Emailmodel.DtEmailFields.Rows[0]["Body"] = myEncodedString;

1

Chrome và Trình duyệt khác hạn chế quyền truy cập của máy chủ vào các tệp cục bộ vì lý do bảo mật. Tuy nhiên, bạn có thể mở trình duyệt ở chế độ truy cập được phép. Chỉ cần mở thiết bị đầu cuối và đi đến thư mục nơi chrome.exe được lưu trữ và viết lệnh sau.

chrome.exe --allow-file-access-from-files

Đọc cái này để biết thêm chi tiết

Tuy nhiên, cách này không hiệu quả với tôi nên tôi đã tạo một tuyến đường khác cho mọi tệp trong một thư mục cụ thể. Do đó, đi đến đường dẫn đó có nghĩa là mở tệp đó.

function getroutes(list){ 
    list.forEach(function(element) { 
        app.get("/"+ element, function(req, res) { 
            res.sendFile(__dirname + "/public/extracted/" + element); 
       }); 
   }); 
}

Tôi đã gọi hàm này truyền danh sách tên tệp trong thư mục __dirname/public/extractedvà nó tạo ra một tuyến đường khác cho từng tên tệp mà tôi có thể hiển thị trên phía máy chủ.


0

Giải pháp này đã làm việc cho tôi trong PHP. Nó mở PDF trong trình duyệt.

// $path is the path to the pdf file
public function showPDF($path) {
    if($path) {
        header("Content-type: application/pdf");
        header("Content-Disposition: inline; filename=filename.pdf");
        @readfile($path);
    }
}

0

Tôi đã gặp phải vấn đề này và đây là giải pháp của tôi cho Angular, tôi đã gói thư mục tài sản Angular của mình trong hàm encodeURIComponent (). Nó đã làm việc. Tuy nhiên, tôi vẫn muốn biết thêm về rủi ro của giải pháp này nếu có:

`` const URL = ${encodeURIComponent(/assets/office/file_2.pdf )} window.open (URL)

I used Angular 9, so this is my url when I clicked open local file:
```http://localhost:4200/%2Fassets%2Foffice%2Ffile_2.pdf```
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.