No se puede abrir el archivo local - Chrome: no se permite cargar el recurso local

104

Navegador de prueba: Versión de Chrome: 52.0.2743.116

Es un javascript simple que es para abrir un archivo de imagen local como 'C: \ 002.jpg'

function run(){

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

   window.open(URL, null);

}
run();

Aquí está mi código de muestra. https://fiddle.jshell.net/q326vLya/3/

Por favor, dame las sugerencias adecuadas.

KBH
fuente
usar <input type=file>para obtener acceso a recursos locales
dandavis

Respuestas:

65

Sepa que esto es un poco antiguo, pero vea muchas preguntas como esta ...

Usamos mucho Chrome en el aula y es imprescindible para trabajar con archivos locales.

Lo que hemos estado usando es "Web Server para Chrome". Lo inicia, elige la carpeta con la que desea trabajar y va a la URL (como 127.0.0.1:port que eligió)

Es un servidor simple y no puede usar PHP, pero para un trabajo simple, podría ser su solución:

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

Leñoso
fuente
1
Woody: ¡muchas gracias! Este enfoque me ayudó. Ejecuto un Tomcat local + un bucket de AWS S3 local en Windows 10. Ahora puedo cambiar entre el servidor AWS en vivo y uno local. Salud. Q
user1723453
20

De acuerdo amigos, entiendo completamente las razones de seguridad detrás de este mensaje de error, pero a veces, necesitamos una solución ... y aquí está la mía. Utiliza ASP.Net (en lugar de JavaScript, en el que se basó esta pregunta) pero es de esperar que sea útil para alguien.

Nuestra aplicación interna tiene una página web donde los usuarios pueden crear una lista de accesos directos a archivos útiles distribuidos por toda nuestra red. Cuando hacen clic en uno de estos accesos directos, queremos abrir estos archivos ... pero, por supuesto, el error de Chrome lo impide.

ingrese la descripción de la imagen aquí

Esta página web utiliza AngularJS 1.x para enumerar los distintos accesos directos.

Originalmente, mi página web intentaba crear directamente un <a href..>elemento apuntando a los archivos, pero esto producía el Not allowed to load local resourceerror " " cuando un usuario hacía clic en uno de estos enlaces.

<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 solución fue reemplazar esos <a href..>elementos con este código, para llamar a una función en mi controlador Angular ...

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

La función en sí es muy 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);
}

Y en mi proyecto ASP.Net, agregué un archivo Handler llamado DownloadExternalFile.aspxque contenía este código:

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

Y eso es.

Ahora, cuando un usuario hace clic en uno de mis enlaces de acceso directo, llama a la OpenAnExternalFilefunción, que abre este archivo .ashx, pasándole la ruta + nombre de archivo del archivo que queremos abrir.

Este código del controlador carga el archivo y luego devuelve su contenido en la respuesta HTTP.

Y, trabajo hecho, la página web abre el archivo externo.

¡Uf! Nuevamente, hay una razón por la que Chrome lanza esta " Not allowed to load local resources" excepción, así que tenga cuidado con esto ... pero estoy publicando este código solo para demostrar que esta es una forma bastante simple de evitar esta limitación.

Solo un último comentario: la pregunta original quería abrir el archivo " C:\002.jpg". No puedes hacer esto. Su sitio web se ubicará en un servidor (con su propia unidad C:) y no tendrá acceso directo a la unidad C: de su usuario. Entonces, lo mejor que puede hacer es usar un código como el mío para acceder a archivos en algún lugar de una unidad de red.

Mike Gledhill
fuente
Suena bien, pero ¿cómo maneja la autorización (permisos de lectura)? ¿Qué sucede si no todos los usuarios pueden ver un archivo determinado? ¿No necesitaría realizar la lectura en nombre del usuario solicitante?
Timi
¿Por qué utiliza un cliente web para abrir un archivo local? Y para mí, intenta abrir C: \ SomeNetworkPath \ ...
Kev
Si no estamos usando angular, ¿todavía es posible?
Ahmad.Tr
Esta fue una respuesta útil, pero afectaría mucho el tiempo de carga de la página web si tiene cientos de imágenes que se procesan y descargan de esta manera a través de este identificador ashx.
Jamshaid Kamran
17

Chrome bloquea específicamente el acceso a archivos locales de esta manera por razones de seguridad.

Aquí hay una solución para habilitar la bandera en Chrome (y abrir su sistema a vulnerabilidades):

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

Scott
fuente
4
Intenté seguir la solución "c: \ path \ chrome.exe" -allow-file-access-from-files pero no puedo abrirlo. Pruebe este sitio web fiddle.jshell.net/q326vLya/3 . ¿Qué estoy haciendo mal?
KBH
7
En GoogleChrome 66 no funciona. Chrome comienza con esa bandera, pero aún muestra que el archivo local no se puede abrir.
Radon8472
16

1) Abra su terminal y escriba

npm install -g http-server

2) Vaya a la carpeta raíz en la que desea que le sirvan los archivos y escriba:

http-server ./

3) Lea la salida de la terminal, http://localhost:8080aparecerá algo .

Se permitirá obtener todo lo que esté allí. Ejemplo:

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

Alex
fuente
http-server tiene un problema que ahora causa errores; aunque puede degradarlo a 0.9 para solucionarlo, consulte stackoverflow.com/questions/56364464/…
Brian Burns
Esta fue la respuesta más simple para mí. Trabajado al 100%. ¡Gracias!
robrecord
9

Existe una solución alternativa al utilizar Web Server para Chrome .
Estos son los pasos:

  1. Agrega la extensión a Chrome.
  2. Elija la carpeta (C: \ images) e inicie el servidor en el puerto que desee.

Ahora acceda fácilmente a su archivo 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();

PD: es posible que deba seleccionar la opción Encabezado CORS desde la configuración avanzada en caso de que se enfrente a algún error de acceso de origen cruzado.

Shwetabh Shekhar
fuente
6

No podrá cargar una imagen fuera del directorio del proyecto o desde un directorio de nivel de usuario, por lo tanto, la "advertencia de no se puede acceder a los recursos locales".

Pero si tuviera que colocar el archivo en una carpeta raíz de su proyecto como en {rootFolder}\Content\my-image.jpgy hacer referencia a él así:

<img src="/Content/my-image.jpg" />
Poncio El Bárbaro
fuente
5

Este problema surge cuando estoy usando PHP como lenguaje del lado del servidor y la solución fue generar codificación base64 de mi imagen antes de enviar el resultado al cliente

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

Creo que puede darle a alguien una idea para crear su propio trabajo

Gracias

Paciencia ruberandinda
fuente
2

Google Chrome no permite cargar recursos locales debido a la seguridad. Chrome necesita una URL http. Internet Explorer y Edge permiten cargar recursos locales, pero Safari, Chrome y Firefox no permiten cargar recursos locales.

Vaya a la ubicación del archivo e inicie Python Server desde allí.

python -m SimpleHttpServer

luego ponga esa url en función:

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);
}
cha
fuente
2

Si tiene php instalado, puede usar el servidor incorporado. Simplemente abra el directorio de destino con archivos y ejecute

php -S localhost:8001
Andrew Zhilin
fuente
1

Si pudiera hacer esto, representaría un gran problema de seguridad, ya que puede acceder a su sistema de archivos y potencialmente actuar sobre los datos disponibles allí ... Afortunadamente, no es posible hacer lo que está tratando de hacer.

Si necesita acceder a los recursos locales, puede intentar iniciar un servidor web en su máquina, y en este caso su método funcionará. Son posibles otras soluciones, como actuar en la configuración de Chrome, pero siempre prefiero la forma limpia, instalando un servidor web local, tal vez en un puerto diferente (¡no, no es tan difícil!).

Ver también:

Prak
fuente
la razón de la regla es más social que técnica; Los navegadores ya hacen un buen trabajo al prevenir el acceso programático a recursos fuera del dominio (por ejemplo, SOP, scripts CDN, etiquetas IMG de vínculos profundos, etc.), pero asusta a la gente al ver su contenido local en una ventana del navegador, incluso si el script no puede decir lo que está mostrando ...
dandavis
1
@dandavis sí, tienes razón, aún así creo que puede ser bueno evitar que esto suceda. Además de los errores en algunas implementaciones (si no puede abrir un recurso local, probablemente esté más seguro), puede haber algunos escenarios específicos en los que otras personas estén mirando su pantalla (aplicaciones para compartir pantalla o simplemente a sus espaldas en su oficina ) y no desea que sus imágenes (potencialmente una tarjeta de crédito o una imagen privada) se puedan abrir con solo visitar algunos sitios web que pueden adivinar la ubicación en su sistema de archivos local ...
Prak
1

Solo necesita reemplazar todas las rutas de red de imágenes por cadenas de bytes en una cadena HTML codificada almacenada. Para esto, requirió HtmlAgilityPack para convertir una cadena Html en un documento Html. https://www.nuget.org/packages/HtmlAgilityPack

Encuentre el código de abajo para convertir cada ruta de red src de imagen (o ruta local) en byte sting. Definitivamente mostrará todas las imágenes con ruta de red (o ruta local) en IE, Chrome y 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
fuente
1

Chrome y otros navegadores restringen el acceso de un servidor a archivos locales por motivos de seguridad. Sin embargo, puede abrir el navegador en el modo de acceso permitido. Simplemente abra la terminal y vaya a la carpeta donde se almacena chrome.exe y escriba el siguiente comando.

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

Lea esto para más detalles

Sin embargo, de esta manera no funcionó para mí, así que hice una ruta diferente para cada archivo en un directorio en particular. Por lo tanto, ir a esa ruta significaba abrir ese archivo.

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

Llamé a esta función pasando la lista de nombre de archivo en el directorio __dirname/public/extractedy creó una ruta diferente para cada nombre de archivo que pude representar en el lado del servidor.

Tanmay_Gupta
fuente
0

Esta solución funcionó para mí en PHP. Abre el PDF en el navegador.

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

Encontré este problema, y ​​aquí está mi solución para Angular, envolví la carpeta de activos de mi Angular en la función encodeURIComponent (). Funcionó. Pero aún así, me gustaría saber más sobre el riesgo de esta solución si hay alguno:

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