Impossible d'ouvrir le fichier local - Chrome: non autorisé à charger la ressource locale

101

Navigateur de test: Version de Chrome: 52.0.2743.116

C'est un simple javascript qui consiste à ouvrir un fichier image à partir du local comme 'C: \ 002.jpg'

function run(){

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

   window.open(URL, null);

}
run();

Voici mon exemple de code. https://fiddle.jshell.net/q326vLya/3/

Veuillez me donner toutes les suggestions appropriées.

KBH
la source
utiliser <input type=file>pour accéder aux ressources locales
dandavis

Réponses:

64

Sachez que c'est un peu vieux, mais voyez de nombreuses questions comme celle-ci ...

Nous utilisons beaucoup Chrome en classe et il est indispensable de travailler avec des fichiers locaux.

Ce que nous utilisons est "Web Server for Chrome". Vous le démarrez, choisissez le dossier avec lequel vous souhaitez travailler et allez à l'URL (comme 127.0.0.1:port que vous avez choisi)

C'est un serveur simple et ne peut pas utiliser PHP mais pour un travail simple, cela pourrait être votre solution:

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

Boisé
la source
1
Woody: merci beaucoup! Cette approche m'a aidé. J'exécute un Tomcat local + un compartiment AWS S3 local sur Windows 10. Je peux maintenant basculer entre le serveur AWS en direct et un serveur local. À votre santé. Q
user1723453
20

D'accord, je comprends parfaitement les raisons de sécurité derrière ce message d'erreur, mais parfois, nous avons besoin d'une solution de contournement ... et voici la mienne. Il utilise ASP.Net (plutôt que JavaScript, sur lequel cette question était basée) mais il sera, espérons-le, utile à quelqu'un.

Notre application interne dispose d'une page Web sur laquelle les utilisateurs peuvent créer une liste de raccourcis vers des fichiers utiles répartis sur notre réseau. Lorsqu'ils cliquent sur l'un de ces raccourcis, nous voulons ouvrir ces fichiers ... mais bien sûr, l'erreur de Chrome empêche cela.

entrez la description de l'image ici

Cette page Web utilise AngularJS 1.x pour lister les différents raccourcis.

À l'origine, ma page Web essayait de créer directement un <a href..>élément pointant vers les fichiers, mais cela a produit l' Not allowed to load local resourceerreur " " lorsqu'un utilisateur cliquait sur l'un de ces liens.

<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 solution était de remplacer ces <a href..>éléments par ce code, d'appeler une fonction dans mon contrôleur angulaire ...

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

La fonction elle-même est très simple ...

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

Et dans mon projet ASP.Net, j'ai ajouté un fichier Handler appelé DownloadExternalFile.aspxqui contenait ce code:

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

Et c'est tout.

Désormais, lorsqu'un utilisateur clique sur l'un de mes liens de raccourci, il appelle le OpenAnExternalFile fonction, qui ouvre ce fichier .ashx, en lui passant le chemin + le nom du fichier que nous voulons ouvrir.

Ce code de gestionnaire charge le fichier, puis renvoie son contenu dans la réponse HTTP.

Et, travail fait, la page Web ouvre le fichier externe.

Phew ! Encore une fois - il y a une raison pour laquelle Chrome lance ceci "Not allowed to load local resources " exception, alors soyez prudent avec ceci ... mais je publie ce code juste pour démontrer qu'il s'agit d'un moyen assez simple de contourner cette limitation.

Juste un dernier commentaire: la question d'origine voulait ouvrir le fichier " C:\002.jpg". Vous ne pouvez pas faire ça. Votre site Web reposera sur un serveur (avec son propre lecteur C:) et n'a pas d'accès direct au lecteur C: de votre utilisateur. Donc, le mieux que vous puissiez faire est d'utiliser un code comme le mien pour accéder aux fichiers quelque part sur un lecteur réseau.

Mike Gledhill
la source
Cela semble bien, mais comment gérez-vous les autorisations (autorisations de lecture)? Que faire si tous les utilisateurs ne sont pas autorisés à afficher un fichier donné? N'auriez-vous pas besoin d'effectuer la lecture au nom de l'utilisateur demandeur?
Timi
Pourquoi utilisez-vous un client Web pour ouvrir un fichier local? Et pour moi, il essaie d'ouvrir C: \ SomeNetworkPath \ ...
Kev
Si nous n'utilisons pas angulaire, est-ce toujours possible?
Ahmad.Tr
C'était une réponse utile mais cela affecterait beaucoup le temps de chargement de la page Web si vous avez des centaines d'images en cours de rendu et de téléchargement de cette manière via cette poignée ashx.
Jamshaid Kamran
17

Chrome bloque spécifiquement l'accès aux fichiers locaux de cette manière pour des raisons de sécurité.

Voici une solution de contournement pour activer l'indicateur dans Chrome (et ouvrir votre système aux vulnérabilités):

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

Scott
la source
4
J'ai essayé de suivre la solution "c: \ path \ chrome.exe" -allow-file-access-from-files mais je ne peux pas l'ouvrir. Veuillez tester ce site Web fiddle.jshell.net/q326vLya/3 . Qu'est-ce que je fais mal?
KBH
6
Sur GoogleChrome 66, cela ne fonctionne pas. Chrome commence avec cet indicateur, mais il montre toujours que le fichier local peut être ouvert.
Radon8472
16

1) Ouvrez votre terminal et tapez

npm install -g http-server

2) Allez dans le dossier racine dans lequel vous souhaitez vous servir des fichiers et tapez:

http-server ./

3) Lisez la sortie du terminal, quelque chose d'un peu http://localhost:8080 apparaîtra.

Tout ce qui s'y trouve pourra être obtenu. Exemple:

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

Alex
la source
Le serveur http a un problème provoquant maintenant des erreurs - vous pouvez le rétrograder à 0.9 pour le corriger - voir stackoverflow.com/questions/56364464/…
Brian Burns
C'était la réponse la plus simple pour moi. A travaillé à 100%. Merci!
robrecord
9

Il existe une solution de contournement à l'aide du serveur Web pour Chrome .
Voici les étapes:

  1. Ajoutez l'extension à Chrome.
  2. Choisissez le dossier (C: \ images) et lancez le serveur sur le port souhaité.

Accédez maintenant facilement à votre fichier local:

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: Vous devrez peut-être sélectionner l'option CORS Header à partir du paramètre avancé au cas où vous rencontriez une erreur d'accès à l'origine croisée.

Shwetabh Shekhar
la source
6

Vous ne pourrez pas charger une image en dehors du répertoire du projet ou à partir d'un répertoire de niveau utilisateur, d'où le "Impossible d'accéder à l'avertissement de ressource locale".

Mais si vous deviez placer le fichier dans un dossier racine de votre projet comme dans {rootFolder}\Content\my-image.jpget le référencer comme suit:

<img src="/Content/my-image.jpg" />
PontiusLeBarbare
la source
5

Ce problème survient lorsque j'utilise PHP comme langage côté serveur et que le contournement consistait à générer un encollage base64 de mon image avant d'envoyer le résultat au client

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

Je pense que peut donner à quelqu'un l'idée de créer son propre travail

Merci

Ruberandinda Patience
la source
2

Google Chrome ne permet pas de charger des ressources locales en raison de la sécurité. Chrome a besoin d'une URL http. Internet Explorer et Edge permettent de charger des ressources locales, mais Safari, Chrome et Firefox ne permettent pas de charger des ressources locales.

Accédez à l'emplacement du fichier et démarrez le serveur Python à partir de là.

python -m SimpleHttpServer

puis mettez cette URL en fonction:

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);
}
shah
la source
2

Si php est installé, vous pouvez utiliser le serveur intégré. Ouvrez simplement le répertoire cible avec les fichiers et exécutez

php -S localhost:8001
Andrew Zhilin
la source
1

Si vous pouviez faire cela, cela représentera un gros problème de sécurité, car vous pouvez accéder à votre système de fichiers, et potentiellement agir sur les données disponibles là-bas ... Heureusement, il n'est pas possible de faire ce que vous essayez de faire.

Si vous avez besoin d'accéder à des ressources locales, vous pouvez essayer de démarrer un serveur Web sur votre machine, et dans ce cas, votre méthode fonctionnera. D'autres solutions de contournement sont possibles, comme agir sur les paramètres de Chrome, mais je préfère toujours la manière propre, en installant un serveur Web local, peut-être sur un port différent (non, ce n'est pas si difficile!).

Voir également:

Prak
la source
la raison de la règle est plus sociale que technique; les navigateurs empêchent déjà l'accès programmatique aux ressources hors domaine (par exemple, SOP, scripts CDN, balises IMG liées en profondeur, etc.), mais cela effraie les gens de voir leur contenu local dans une fenêtre de navigateur, même si le le script ne peut pas dire ce qu'il montre ...
dandavis
1
@dandavis oui, vous avez raison, je crois toujours qu'il peut être bon d'empêcher que cela se produise. Outre les bogues dans certaines implémentations (si vous ne pouvez pas ouvrir une ressource locale, vous êtes probablement plus en sécurité), il peut y avoir des scénarios spécifiques où d'autres personnes regardent votre écran (applications de partage d'écran, ou simplement derrière votre dos dans votre bureau ) et vous ne voulez pas que vos images (potentiellement une carte de crédit ou une image privée) puissent être ouvertes simplement en visitant certains sites Web qui peuvent deviner l'emplacement sur votre système de fichiers local ...
Prak
1

Il vous suffit de remplacer tous les chemins réseau de l'image par des chaînes d'octets dans la chaîne HTML encodée stockée. Pour cela, vous avez besoin de HtmlAgilityPack pour convertir la chaîne Html en document Html. https://www.nuget.org/packages/HtmlAgilityPack

Trouvez le code ci-dessous pour convertir chaque chemin réseau src d'image (ou chemin local) en octet sting. Il affichera certainement toutes les images avec le chemin réseau (ou le chemin local) dans IE, Chrome et 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;
Maishidh Mandviwala
la source
1

Chrome et d'autres navigateurs restreignent l'accès d'un serveur aux fichiers locaux pour des raisons de sécurité. Cependant, vous pouvez ouvrir le navigateur en mode d'accès autorisé. Ouvrez simplement le terminal et allez dans le dossier où chrome.exe est stocké et écrivez la commande suivante.

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

Lisez ceci pour plus de détails

De cette façon, cependant, ne fonctionnait pas pour moi, donc j'ai fait une route différente pour chaque fichier dans un répertoire particulier. Par conséquent, accéder à ce chemin signifiait ouvrir ce fichier.

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

J'ai appelé cette fonction en passant la liste des noms de fichiers dans le répertoire __dirname/public/extractedet cela a créé une route différente pour chaque nom de fichier que j'ai pu rendre côté serveur.

Tanmay_Gupta
la source
0

Cette solution a fonctionné pour moi en PHP. Il ouvre le PDF dans le navigateur.

// $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);
    }
}
rgoot
la source
0

J'ai rencontré ce problème, et voici ma solution pour Angular, j'ai enveloppé le dossier d'actifs de mon Angular dans la fonction encodeURIComponent (). Ça a marché. Mais encore, j'aimerais en savoir plus sur le risque de cette solution s'il y en a:

`` `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```
wimblywombly
la source