Impossibile aprire il file locale - Chrome: non è consentito caricare la risorsa locale


99

Browser di prova: versione di Chrome: 52.0.2743.116

È un semplice javascript che serve per aprire un file immagine da locale come 'C: \ 002.jpg'

function run(){

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

   window.open(URL, null);

}
run();

Ecco il mio codice di esempio. https://fiddle.jshell.net/q326vLya/3/

Per favore dammi qualche suggerimento adatto.


utilizzare <input type=file>per accedere alle risorse locali
dandavis

Risposte:


62

Sappi che è un po 'vecchio, ma vedi molte domande come questa ...

Usiamo molto Chrome in classe ed è fondamentale lavorare con i file locali.

Quello che abbiamo utilizzato è "Web Server per Chrome". Lo avvii, scegli la cartella con cui vuoi lavorare e vai all'URL (come 127.0.0.1:port che hai scelto)

È un server semplice e non può usare PHP ma per un lavoro semplice, potrebbe essere la tua soluzione:

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


1
Woody: grazie mille! Questo approccio mi ha aiutato. Eseguo un Tomcat locale + un bucket AWS S3 locale su Windows 10. Ora posso passare dal server AWS live a uno locale. Saluti. Q
user1723453

20

Ok gente, capisco perfettamente i motivi di sicurezza dietro questo messaggio di errore, ma a volte abbiamo bisogno di una soluzione alternativa ... ed ecco la mia. Utilizza ASP.Net (piuttosto che JavaScript, su cui si basava questa domanda) ma si spera che possa essere utile a qualcuno.

La nostra app interna ha una pagina web in cui gli utenti possono creare un elenco di collegamenti a file utili sparsi in tutta la nostra rete. Quando fanno clic su una di queste scorciatoie, vogliamo aprire questi file ... ma ovviamente l'errore di Chrome lo impedisce.

inserisci qui la descrizione dell'immagine

Questa pagina web utilizza AngularJS 1.x per elencare le varie scorciatoie.

In origine, la mia pagina web stava tentando di creare direttamente un <a href..>elemento che puntava ai file, ma questo produceva l' Not allowed to load local resourceerrore " " quando un utente faceva clic su uno di questi link.

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

La soluzione era sostituire quegli <a href..>elementi con questo codice, per chiamare una funzione nel mio controller Angular ...

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

La funzione stessa è molto semplice ...

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

E nel mio progetto ASP.Net, ho aggiunto un file Handler chiamato DownloadExternalFile.aspxche conteneva questo codice:

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

E questo è tutto.

Ora, quando un utente fa clic su uno dei miei collegamenti di scelta rapida, chiama la OpenAnExternalFilefunzione, che apre questo file .ashx, passandogli il percorso + il nome del file che vogliamo aprire.

Questo codice gestore carica il file, quindi ritrasmette il contenuto nella risposta HTTP.

E, fatto il lavoro, la pagina web apre il file esterno.

Phew! Ancora una volta, c'è una ragione per cui Chrome lancia questa " Not allowed to load local resources" eccezione, quindi procedi con cautela ... ma sto postando questo codice solo per dimostrare che questo è un modo abbastanza semplice per aggirare questa limitazione.

Solo un ultimo commento: la domanda originale voleva aprire il file " C:\002.jpg". Non puoi farlo. Il tuo sito web risiederà su un server (con la propria unità C:) e non ha accesso diretto all'unità C: dell'utente. Quindi il meglio che puoi fare è usare un codice come il mio per accedere ai file da qualche parte su un'unità di rete.


Suona bene, ma come gestisci l'autorizzazione (permessi di lettura)? E se non tutti gli utenti sono autorizzati a visualizzare un determinato file? Non avresti bisogno di eseguire la lettura a nome dell'utente richiedente?
Timi

Perché usi un webclient per aprire un file locale? E per me, prova ad aprire C: \ SomeNetworkPath \ ...
Kev

Se non stiamo usando angolare è ancora possibile?
Ahmad Tr

Questa è stata una risposta utile, ma influirebbe molto sul tempo di caricamento della pagina web se centinaia di immagini vengono renderizzate e scaricate in questo modo tramite questo handle di ashx.
Jamshaid Kamran

17

Chrome blocca specificamente l'accesso ai file locali in questo modo per motivi di sicurezza.

Ecco una soluzione alternativa per abilitare il flag in Chrome (e aprire il tuo sistema alle vulnerabilità):

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


4
Ho provato a seguire la soluzione "c: \ path \ chrome.exe" -allow-file-access-from-files ma non riesco ad aprirla. Si prega di testare questo sito web fiddle.jshell.net/q326vLya/3 . Che cosa sto facendo di sbagliato?
KBH

5
Su GoogleChrome 66 non funziona. Chrome inizia con quel flag, ma mostra ancora che il file locale non può essere aperto.
Radon8472

16

1) Apri il tuo terminale e digita

npm install -g http-server

2) Vai alla cartella principale in cui vuoi che ti servano i file e digita:

http-server ./

3) Leggi l'output del terminale, http://localhost:8080apparirà qualcosa di simile .

Tutto quello che c'è sopra potrà essere preso. Esempio:

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


http-server ha un problema che ora causa errori - puoi eseguire il downgrade a 0.9 anche se per risolverlo - vedi stackoverflow.com/questions/56364464/…
Brian Burns

Questa è stata la risposta più semplice per me. Ha funzionato al 100%. Grazie!
robrecord

9

Esiste una soluzione alternativa utilizzando Web Server per Chrome .
Ecco i passaggi:

  1. Aggiungi l'estensione a Chrome.
  2. Scegli la cartella (C: \ immagini) e avvia il server sulla porta desiderata.

Ora accedi facilmente al tuo file locale:

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: potrebbe essere necessario selezionare l'opzione CORS Header dalle impostazioni avanzate in caso di errore di accesso cross origin.


5

Non sarai in grado di caricare un'immagine al di fuori della directory del progetto o da una directory a livello utente, quindi il messaggio "Impossibile accedere alle risorse locali".

Ma se dovessi posizionare il file in una cartella principale del tuo progetto come in {rootFolder}\Content\my-image.jpge fare riferimento ad esso in questo modo:

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

4

Questo problema si verifica quando utilizzo PHP come linguaggio lato server e il lavoro è stato quello di generare l'enconding base64 della mia immagine prima di inviare il risultato al client

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

Penso che possa dare a qualcuno l'idea di creare il proprio lavoro in giro

Grazie


2

Google Chrome non consente di caricare risorse locali a causa della sicurezza. Chrome richiede l'URL http. Internet Explorer ed Edge consentono di caricare risorse locali, ma Safari, Chrome e Firefox non consentono di caricare risorse locali.

Vai al percorso del file e avvia il server Python da lì.

python -m SimpleHttpServer

quindi metti quell'URL in funzione:

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

Se hai installato php, puoi usare il server integrato. Basta aprire la directory di destinazione con i file ed eseguire

php -S localhost:8001

1

Se potessi farlo, rappresenterebbe un grosso problema di sicurezza, in quanto puoi accedere al tuo filesystem e potenzialmente agire sui dati disponibili lì ... Fortunatamente non è possibile fare quello che stai cercando di fare.

Se hai bisogno di risorse locali per accedere, puoi provare ad avviare un server web sulla tua macchina, e in questo caso il tuo metodo funzionerà. Sono possibili altre soluzioni alternative, come agire sulle impostazioni di Chrome, ma io preferisco sempre il modo pulito, installando un server web locale, magari su una porta diversa (no, non è così difficile!).

Guarda anche:


il motivo della regola è più sociale che tecnico; i browser fanno un buon lavoro nel prevenire già l'accesso programmatico a risorse esterne al dominio (ad es. SOP, script CDN, tag IMG con link profondi, ecc.), ma fa impazzire le persone vedere i loro contenuti locali in una finestra del browser, anche se il lo script non può dire cosa sta mostrando ...
dandavis

1
@dandavis si, hai ragione, comunque credo che possa essere un bene evitare che ciò accada. A parte i bug in alcune implementazioni (se non puoi aprire una risorsa locale, probabilmente sei più sicuro), possono esserci alcuni scenari specifici in cui altre persone guardano il tuo schermo (app di condivisione dello schermo o semplicemente dietro la schiena nel tuo ufficio ) e non vuoi che le tue immagini (potenzialmente una carta di credito o un'immagine privata) possano essere aperte semplicemente visitando alcuni siti Web che possono indovinare la posizione sul tuo filesystem locale ...
Prak

1

È sufficiente sostituire tutti i percorsi di rete delle immagini con stringhe di byte nella stringa HTML codificata memorizzata. Per questo hai richiesto HtmlAgilityPack per convertire la stringa Html in un documento Html. https://www.nuget.org/packages/HtmlAgilityPack

Trova sotto il codice per convertire ogni percorso di rete src dell'immagine (o percorso locale) in byte sting. Sicuramente mostrerà tutte le immagini con percorso di rete (o percorso locale) in IE, Chrome e 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;

0

Questa soluzione ha funzionato per me in PHP. Apre il PDF nel browser.

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

Chrome e altri browser limitano l'accesso di un server ai file locali per motivi di sicurezza. Tuttavia è possibile aprire il browser in modalità di accesso consentito. Basta aprire il terminale e andare nella cartella in cui è memorizzato chrome.exe e scrivere il seguente comando.

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

Leggi questo per maggiori dettagli

In questo modo, tuttavia, non ha funzionato per me, quindi ho creato un percorso diverso per ogni file in una determinata directory. Pertanto, andare a quel percorso significava aprire quel file.

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

Ho chiamato questa funzione passando l'elenco dei nomi di file nella directory __dirname/public/extractede ha creato un percorso diverso per ogni nome di file che sono stato in grado di rendere sul lato server.


0

Ho riscontrato questo problema ed ecco la mia soluzione per Angular, ho inserito la cartella degli asset di Angular nella funzione encodeURIComponent (). Ha funzionato. Tuttavia, mi piacerebbe saperne di più sul rischio di questa soluzione se ce ne sono:

`` 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```
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.