无法打开本地文件-Chrome:不允许加载本地资源


99

测试浏览器: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/

请给我任何合适的建议。


用于<input type=file>访问当地资源
dandavis '16

Answers:


62

知道这有点老了,但是看到很多这样的问题...

我们在课堂上经常使用Chrome,这是处理本地文件的必备条件。

我们一直在使用的是“ Chrome浏览器的Web服务器”。启动它,选择希望使用的文件夹,然后转到URL(例如您选择的127.0.0.1:port)

这是一个简单的服务器,不能使用PHP,但是为了简单的工作,可能是您的解决方案:

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


1
伍迪:非常感谢!这种方法对我有所帮助。我在Windows 10上运行本地Tomcat +本地AWS S3存储桶。现在,我可以在实时AWS服务器和本地AWS服务器之间切换。干杯。Q
user1723453 '10

20

好的,我完全理解了此错误消息背后的安全原因,但有时,我们确实需要解决方法……这是我的。它使用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项目中,我添加了一个名为Handler的文件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响应中。

并且,完成工作后,该网页将打开外部文件。

Ph!再说一次-Chrome引发此“ Not allowed to load local resources”异常是有原因的,因此请谨慎行事...但是我发布此代码只是为了证明这是解决此限制的相当简单的方法。

最后一个评论:最初的问题是要打开文件“ C:\002.jpg”。你不能做到这一点。您的网站将位于一台服务器上(具有自己的C:驱动器),并且不能直接访问用户自己的C:驱动器。因此,您能做的最好的事情就是使用像我的代码来访问网络驱动器上某处的文件。


听起来不错,但是您如何处理授权(读取权限)?如果不是所有用户都可以查看给定的文件怎么办?您是否不需要以发出请求的用户的名义执行读取操作?
Timi

为什么使用Web客户端打开本地文件?对我来说,它尝试打开C:\ SomeNetworkPath \ ...
Kev

如果我们不使用角度,还有可能吗?
Ahmad.Tr

这是一个有用的答案,但是如果您通过ashx句柄像这样渲染和下载数百张图片,则将极大地影响网页的加载时间。
Jamshaid Kamran

17

出于安全原因,Chrome专门以这种方式阻止了本地文件访问。

以下是一种在Chrome中启用该标志(并向系统开放漏洞)的解决方法:

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


4
我尝试遵循解决方案“ c:\ path \ chrome.exe” -allow-file-access-from-files,但无法打开它。请测试此网站fiddle.jshell.net/q326vLya/3。我究竟做错了什么?
KBH

5
在GoogleChrome 66上无法正常工作。Chrome以该标志开头,但仍显示无法打开本地文件。
Radon8472

16

1)打开终端并输入

npm install -g http-server

2)转到您要为其提供文件的根文件夹,然后键入:

http-server ./

3)读取终端的输出,http://localhost:8080将会出现一些错误。

那里的一切都将被允许拿到。例:

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


HTTP服务器现在已经导致错误的问题-你可以将它降级到0.9,虽然对固定-看stackoverflow.com/questions/56364464/...
布赖恩·伯恩斯

对我来说,这是最简单的答案。工作了100%。谢谢!
robrecord

9

有一种使用Web Server for 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 Header选项。


5

您将无法从项目目录或用户级别目录中加载图像,因此出现“无法访问本地资源警告”。

但是,如果要将文件放置在项目的根文件夹中(如in),{rootFolder}\Content\my-image.jpg并按如下所示引用它:

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

4

当我使用PHP作为服务器端语言并且解决方法是在将结果发送到客户端之前生成我的映像的base64编码时,就会出现此问题

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

我认为可能会给某人一个想法,让他围绕自己创作

谢谢


2

出于安全原因,Google Chrome浏览器不允许加载本地资源。Chrome需要http网址。Internet Explorer和Edge允许加载本地资源,但是Safari,Chrome和Firefox不允许加载本地资源。

转到文件位置,然后从那里启动Python Server。

python -m SimpleHttpServer

然后将该网址放入函数中:

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

如果您安装了php,则可以使用内置服务器。只需使用文件打开目标目录并运行

php -S localhost:8001

1

如果您可以这样做,那么它将代表一个严重的安全问题,因为您可以访问文件系统,并可能对该文件系统中的可用数据进行操作...幸运的是,您无法做您想做的事情。

如果需要访问本地资源,则可以尝试在计算机上启动Web服务器,在这种情况下,您的方法将起作用。也可以采用其他解决方法,例如根据Chrome设置进行操作,但我始终更喜欢干净的方法,可以在其他端口上安装本地Web服务器(不,这并不难!)。

也可以看看:


该规则的原因是社会性而非技术性;浏览器做防止编程方式访问过域资源已经(如SOP,CDN的脚本,深联IMG标签等)的一个很好的工作,但它怪胎的人出来在浏览器窗口的本地内容,即使脚本无法分辨显示的内容...
dandavis '16

1
@dandavis是的,您是对的,但我仍然相信防止发生这种情况可能会很好。除了某些实现中的错误(如果您无法打开本地资源,您可能会更安全)之外,在某些特定情况下,其他人正在看着您的屏幕(屏幕共享应用程序,或者只是在办公室的背后) ),并且您不希望仅通过访问可以猜测本地文件系统上位置的某些网站来打开图像(可能是信用卡图像或私人图像)...
Prak

1

您只需要将所有图像网络路径替换为存储的已编码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;

0

该解决方案在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);
    }
}

0

由于安全原因,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它为每个文件名创建了一条不同的路由,并能够在服务器端进行渲染。


0

我遇到了这个问题,这是我对Angular的解决方案,我将Angular的资产文件夹包装在encodeURIComponent()函数中。有效。但是,如果有任何问题,我想进一步了解此解决方案的风险:

常量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```
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.