Не удается открыть локальный файл - Chrome: запрещено загружать локальный ресурс

Тестовый браузер: версия Chrome: 52.0.2743.116

Это простой javascript, который должен открыть файл изображения из локального файла, например, C:\002.jpg.

function run(){

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

   window.open(URL, null);

}
run();

Вот мой пример кода. https://fiddle.jshell.net/q326vLya/3/

Пожалуйста, дайте мне любые подходящие предложения.

17 ответов

Решение

Знайте, что это довольно старое, но посмотрите много вопросов, как это...

Мы часто используем Chrome в классе, и это необходимо для работы с локальными файлами.

То, что мы использовали, это "Веб-сервер для Chrome". Вы запускаете его, выбираете папку, с которой хотите работать, и переходите по URL (например, 127.0.0.1: выбранный вами порт)

Это простой сервер, и он не может использовать PHP, но для простой работы может быть вашим решением:

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

1) Откройте свой терминал и введите

npm install -g http-server

2) Перейдите в корневую папку, в которую вы хотите предоставить файлы, и введите:

http-server ./

3) Прочитать вывод терминала, что-то вроде http://localhost:8080 будет появляться.

Все там будет разрешено получить. Пример:

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

Ладно, ребята, я полностью понимаю причины безопасности, стоящие за этим сообщением об ошибке, но иногда нам нужен обходной путь... и вот мой. Он использует ASP.Net (а не JavaScript, на котором был основан этот вопрос), но, надеюсь, он кому-нибудь пригодится.

Наше собственное приложение имеет веб-страницу, где пользователи могут создать список ярлыков для полезных файлов, распространяемых по всей нашей сети. Когда они нажимают на один из этих ярлыков, мы хотим открыть эти файлы... но, конечно, ошибка Chrome предотвращает это.

Эта веб-страница использует AngularJS 1.x для перечисления различных ярлыков.

Первоначально моя веб-страница пыталась создать <a href..> элемент, указывающий на файлы, но это произвелоNot allowed to load local resource"ошибка, когда пользователь нажимал на одну из этих ссылок.

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

Решение было заменить те <a href..> элементы с этим кодом, чтобы вызвать функцию в моем контроллере Angular...

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

Сама функция очень проста...

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

И в моем проекте ASP.Net я добавил файл обработчика под названием DownloadExternalFile.aspx который содержал этот код:

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

И это все.

Теперь, когда пользователь нажимает на одну из моих ссылок ярлыков, он вызывает OpenAnExternalFile функция, которая открывает этот файл.ashx, передавая ему путь + имя файла, который мы хотим открыть.

Этот код обработчика загружает файл, а затем передает его содержимое обратно в ответ HTTP.

И, работа сделана, веб-страница открывает внешний файл.

Фу! Опять же - есть причина, почему Chrome кидает этоNot allowed to load local resources"Исключение, так что осторожно с этим... но я публикую этот код, чтобы продемонстрировать, что это довольно простой способ обойти это ограничение.

Только один последний комментарий: оригинальный вопрос хотел открыть файл "C:\002.jpg". Вы не можете сделать это. Ваш веб-сайт будет находиться на одном сервере (со своим собственным диском C:) и не будет иметь прямого доступа к собственному диску C: вашего пользователя. Поэтому лучшее, что вы можете сделать, - это использовать код, подобный моему, для доступа файлы где-то на сетевом диске.

Chrome специально блокирует доступ к локальным файлам таким образом из соображений безопасности.

Вот статья, чтобы обойти флаг в Chrome (и открыть вашу систему для уязвимостей):

http://www.chrome-allow-file-access-from-file.com/

Существует обходной путь с использованием веб-сервера для Chrome.
Вот шаги:

  1. Добавьте расширение к Chrome.
  2. Выберите папку (C:\images) и запустите сервер на нужном порту.

Теперь легко получить доступ к вашему локальному файлу:

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

PS: вам может потребоваться выбрать опцию Заголовок CORS в дополнительных настройках, если вы столкнетесь с любой ошибкой или ошибкой доступа к другому источнику.

Вы не сможете загрузить изображение вне каталога проекта или из каталога уровня пользователя, поэтому "не может получить доступ к предупреждению о локальных ресурсах".

Но если вы поместите файл в корневую папку вашего проекта, как в myProject\Content\ и ссылался на это так:

<img src="/Content/myfolder/myimage.jpg" />

Эта проблема возникает, когда я использую PHP в качестве языка на стороне сервера, и обходной путь заключался в том, чтобы сгенерировать end64 моего изображения base64 перед отправкой результата клиенту

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

Я думаю, может дать кому-то идею создать вокруг себя

Спасибо

Google Chrome не позволяет загружать локальные ресурсы из-за безопасности. Хром нужен http URL. Internet Explorer и Edge позволяют загружать локальные ресурсы, но Safari, Chrome и Firefox не позволяют загружать локальные ресурсы.

Перейдите в папку с файлом и запустите Python Server оттуда.

python -m SimpleHttpServer

затем поместите этот URL в функцию:

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

Если у вас установлен php - вы можете использовать встроенный сервер. Просто откройте целевой каталог с файлами и запустите

php -S localhost:8001

Это для google-chrome-extension

      const url = "file:///C:\002.jpg"
chrome.tabs.create({url, active:true})

manifest.json

      {
  "name": "",
  "manifest_version": 3,
  "permissions": [
    "activeTab",
    "tabs"
  ],
  // ...
}

Если вы могли бы сделать это, это будет представлять большую проблему безопасности, так как вы можете получить доступ к своей файловой системе и потенциально воздействовать на имеющиеся там данные... К счастью, невозможно сделать то, что вы пытаетесь сделать.

Если вам нужен доступ к локальным ресурсам, вы можете попробовать запустить веб-сервер на вашем компьютере, и в этом случае ваш метод будет работать. Возможны и другие обходные пути, например, работа с настройками Chrome, но я всегда предпочитаю чистый способ, установить локальный веб-сервер, возможно, на другой порт (нет, это не так сложно!).

Смотрите также:

Я столкнулся с этой проблемой, и вот мое решение для Angular. Я обернул папку с ресурсами Angular в функцию encodeURIComponent(). Это сработало. Но все же я хотел бы узнать больше о риске этого решения, если он есть:

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

Вам просто нужно заменить все пути к сетям изображений на строки байтов в сохраненной кодированной строке HTML. Для этого вам понадобился HtmlAgilityPack для преобразования строки HTML в документ HTML. https://www.nuget.org/packages/HtmlAgilityPack

Найдите код ниже, чтобы преобразовать каждый сетевой образ (или локальный путь) src в байтовый код. Он определенно отобразит все изображения с сетевым путем (или локальным путем) в IE, Chrome и 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;

Chrome и другие браузеры ограничивают доступ сервера к локальным файлам из соображений безопасности. Однако вы можете открыть браузер в режиме разрешенного доступа. Просто откройте терминал, перейдите в папку, где хранится chrome.exe, и напишите следующую команду.

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

Прочтите это для более подробной информации

Однако этот способ не сработал для меня, поэтому я сделал другой маршрут для каждого файла в определенном каталоге. Следовательно, переход по этому пути означал открытие этого файла.

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

Я вызвал эту функцию, передав список имен файлов в каталоге __dirname/public/extracted и он создал другой маршрут для каждого имени файла, который я смог отобразить на стороне сервера.

В случае аудиофайлов, когда вы даете <audio src="C://somePath"/>, это вызывает ошибку: cannot load local resource. Это имеет смысл, потому что любая веб-страница не может просто указать локальный путь и получить доступ к вашим личным файлам.

Если вы пытаетесь воспроизвести аудио с динамическими путями, изменив src property через JS, то вот пример реализации с использованием сервера Flask и HTML.

server.py

      @app.route("/")
    def home():
        return render_template('audioMap.html')

@app.route('/<audio_file_name>')
def view_method(audio_file_name):
    path_to_audio_file = "C:/Audios/yourFolderPath" + audio_file_name
    return send_file(
         path_to_audio_file, 
         mimetype="audio/mp3", 
         as_attachment=True, 
         attachment_filename="test.mp3")

audioMap.html

      {% raw %}
<!DOCTYPE html>
<html>
<body>
    AUDIO: <audio src="Std.mp3" controls  >
</body>
</html>
{% endraw %}

Объяснение:

Когда вы указываете имя аудиофайла под src свойство, это создает запрос на получение в колбе, как показано

      127.0.0.1 - - [04/May/2021 21:33:12] "GET /Std.mp3 HTTP/1.1" 200 -

Как видите, фляга отправила запрос Get для Std.mp3файл. Итак, чтобы обслужить этот запрос на получение, мы написали конечную точку, которая принимает имя аудиофайла, считывает его из локального каталога и возвращает обратно. Следовательно, звук отображается в пользовательском интерфейсе.

Примечание. Это работает, только если вы визуализируете свой HTML-файл с помощью метода render_template через flask или, скажем, используя flask в качестве веб-сервера.

Это решение работало для меня в PHP. Это открывает PDF в браузере.

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

Google Chrome не позволяет загружать локальные ресурсы из соображений безопасности. Существует простое решение этой проблемы.

1.установите плагин live-сервера в vscode

2. откройте html-файл на живом сервере

xZidLn.png

Другие вопросы по тегам