web-dev-qa-db-fra.com

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

Navigateur de test: Version de Chrome: 52.0.2743.116

C'est un simple javascript qui consiste à ouvrir un fichier image d'un répertoire local, tel que '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/

S'il vous plaît donnez-moi des suggestions appropriées.

65
KBH

Sache que c'est un peu vieux, mais vois beaucoup de questions comme ça ...

Nous utilisons beaucoup Chrome dans la salle de 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 dans 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

43
Woody

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

Notre application interne comporte une page Web sur laquelle les utilisateurs peuvent créer une liste de raccourcis vers des fichiers utiles répartis sur l'ensemble de 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 l'empêche.

enter image description here

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

À l'origine, ma page Web tentait de créer directement un élément <a href..> pointant vers les fichiers, mais cela produisait l'erreur "Not allowed to load local resource" 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 consistait à remplacer ces éléments <a href..> par ce code, à appeler une fonction dans mon contrôleur Angular ...

<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.aspx qui 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 la fonction OpenAnExternalFile, qui ouvre ce fichier .ashx en lui transmettant le chemin + nom du fichier à ouvrir.

Ce code de gestionnaire charge le fichier, puis transmet 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 lève cette exception "Not allowed to load local resources", alors soyez prudent avec ceci ... mais je publie ce code juste pour démontrer qu'il s'agit d'un moyen assez simple autour de cette limitation.

Un dernier commentaire: la question initiale voulait ouvrir le fichier "C:\002.jpg". Vous ne pouvez pas faire ceci. Votre site Web sera assis sur un serveur (avec son propre lecteur C:) et n'aura aucun accès direct au lecteur C: de votre utilisateur. Le mieux que vous puissiez faire est donc d'utiliser un code comme le mien pour accéder aux fichiers quelque part sur un lecteur réseau.

15
Mike Gledhill

Chrome bloque spécifiquement cet accès aux fichiers locaux pour des raisons de sécurité.

Voici un article pour contourner l'indicateur dans Chrome (et ouvrir votre système aux vulnérabilités):

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

13
Scott

Il existe une solution de contournement utilisant Web Server for Chrome .
Voici les étapes:

  1. Ajoutez l'extension à chrome.
  2. Choisissez le dossier (C:\images) et lancez le serveur sur le port de votre choix.

Maintenant, accédez 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 En-tête CORS dans les paramètres avancés si vous rencontrez une erreur quelconque lors de l'accès croisé à l'origine.

5
Shwetabh Shekhar

1) Ouvrez votre terminal et tapez

npm install -g http-server

2) Accédez au dossier racine dans lequel vous souhaitez vous servir, puis tapez:

http-server ./

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

Tout ce qui se trouve là-bas sera autorisé à être obtenu. Exemple:

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

5
Marcelo Rafael

Vous ne pourrez pas charger une image en dehors du répertoire du projet ou d'un répertoire au niveau utilisateur. Par conséquent, l'avertissement "impossible d'accéder aux ressources locales".

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

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

Si vous pouviez le faire, cela poserait un gros problème de sécurité, car vous pouvez accéder à votre système de fichiers et potentiellement exploiter 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 ordinateur. Dans ce cas, votre méthode fonctionnera. D'autres solutions de contournement sont possibles, telles que le fait d'agir sur les paramètres Chrome, mais je préfère toujours la méthode simple, en installant un serveur Web local, peut-être sur un autre port (non, ce n'est pas si difficile!).

Voir également:

1
Prak

Ce problème survient lorsque j'utilise PHP en tant que langage côté serveur et que le travail à effectuer consistait à générer l'encombrement en 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 autour

Merci

1

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

Recherchez le code ci-dessous pour convertir chaque chemin d'accès réseau (ou local) de l'image src en octets. Il affichera définitivement 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;
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);
    }
}
0
rgoot

Google Chrome ne permet pas de charger des ressources locales en raison de la sécurité. Chrome nécessite http url. 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 cet emplacement.

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