181

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

请给我任何合适的建议。

16 个答案

113

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

我们一直使用的是“Web Server for Chrome”。您启动它,选择想要使用的文件夹并转到 URL(例如 127.0.0.1:您选择的端口)

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

chrome 一个已过时的插件 web server for chrome 

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

55

1)打开终端并输入

npm install -g http-server

2) 转到您想要为您提供文件的根文件夹并键入:

http-server ./

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

那里的一切都将被允许获得。例子:

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

33

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

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

唷!再说一遍 - Chrome 抛出这个“”异常是有原因的Not allowed to load local resources,所以要小心处理这个......但我发布这段代码只是为了证明这是解决这个限制的一个相当简单的方法。

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

  • 1
    听起来不错,但是如何处理授权(读取权限)?如果不允许所有用户查看给定文件怎么办?您不需要以请求用户的名义执行读取吗? 
    – 蒂米
     2019 年 9 月 10 日 8:44
  • 为什么使用网络客户端打开本地文件?对于我来说,它尝试打开 C:\SomeNetworkPath\... 
    – 凯夫
     2020 年 1 月 15 日 11:05 
  • 如果我们不使用 Angular 还可以吗?  2020 年 4 月 6 日 22:22
  • 这是一个有用的答案,但如果您有数百张图片通过 ashx 句柄像这样渲染和下载,它会极大地影响网页的加载时间。  2020 年 5 月 17 日 5:09
  • 1
    @Marie - 谢谢您的反馈。说实话,以前从来没有人有礼貌地解释过为什么他们对我投反对票,所以我很感激。我确实同意,它确实提供了围绕 Chrome 安全性的后门,但在我公司的内部应用程序中,需要此解决方案,并且它是一个救星。但是,是的,正如我所说......小心行事!  2021 年 3 月 10 日 16:04
18

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

这里有一篇文章可以解决 Chrome 中的标志(并使您的系统面临漏洞):

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

13

有一个使用Chrome Web Server 的解决方法。
步骤如下:

  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 标头选项,以防遇到任何跨源访问错误。

7

当我使用 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);

我认为可能会给某人一些想法来创造自己的工作

谢谢

4

出于安全考虑,Google Chrome 不允许加载本地资源。Chrome 需要 http url。Internet Explorer和Edge允许加载本地资源,但Safari、Chrome和Firefox不允许加载本地资源。

转到文件位置并从那里启动 Python 服务器。

python -m SimpleHttpServer

然后将该 url 放入函数中:

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

如果你能做到这一点,这将代表一个很大的安全问题,因为你可以访问你的文件系统,并可能对那里可用的数据采取行动……幸运的是,你不可能做你想做的事情。

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

也可以看看:

  • 1
    制定该规则的原因更多是社会原因而非技术原因;浏览器已经很好地防止了对域外资源的编程访问(例如,SOP、CDN 脚本、深层链接的 IMG 标签等),但是人们在浏览器窗口中看到本地内容时会感到害怕即使脚本无法告诉它正在显示什么...  2016 年 8 月 17 日 23:09 
  • 1
    @dandavis 是的,你是对的,但我仍然相信防止这种情况发生是有好处的。除了某些实现中的错误(如果您无法打开本地资源,您可能会更安全)之外,在某些特定情况下,其他人可能正在查看您的屏幕(屏幕共享应用程序,或者只是在您的办公室背后) )并且您不希望您的图像(可能是信用卡或私人图像)可以通过访问一些可以猜测您本地文件系统上的位置的网站来打开...... 
    – 
     2016 年 8 月 17 日晚上 11:55
2

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

php -S localhost:8001
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;
1

由于安全原因,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,它为每个文件名创建了一个不同的路由,我可以在服务器端渲染该路由。

1

我遇到了这个问题,这是我的 Angular 解决方案,我将 Angular 的 asset 文件夹包装在encodeURIComponent() 函数中。有效。但是,我仍然想更多地了解此解决方案的风险(如果有):

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

这是用于google-chrome-extension

const url = "file:///C:\002.jpg"
chrome.tabs.create({url, active:true})

清单.json

{
  "name": "",
  "manifest_version": 3,
  "permissions": [
    "activeTab",
    "tabs"
  ],
  // ...
}

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

对于音频文件,当您给出 时<audio src="C://somePath"/>,会抛出一个错误,指出cannot load local resource. 这是有道理的,因为任何网页都不能简单地给出本地路径并访问您的私人文件。

如果您尝试src property通过 JS 更改来使用动态路径播放音频,那么这里是使用 Flask 服务器和 HTML 的示例实现。

server.py

@app.route("/")
    def home():
        return render_template('audioMap.html')

@app.route('/<audio_file_name>')
def view_method(audio_file_name):
    path_to_audio_file = "C:/Audios/yourFolderPath" + audio_file_name
    return send_file(
         path_to_audio_file, 
         mimetype="audio/mp3", 
         as_attachment=True, 
         attachment_filename="test.mp3")

音频映射.html

{% raw %}
<!DOCTYPE html>
<html>
<body>
    AUDIO: <audio src="Std.mp3" controls  >
</body>
</html>
{% endraw %}

解释:

当您在属性下给出音频文件名时src,这会在烧瓶中创建一个获取请求,如下所示

127.0.0.1 - - [04/May/2021 21:33:12] "GET /Std.mp3 HTTP/1.1" 200 -

正如您所看到的,Flask 已发送了对该Std.mp3文件的 Get 请求。因此,为了服务这个 get 请求,我们编写了一个端点,它获取音频文件名,从本地目录读取它,然后将其返回。因此音频会显示在用户界面上。

注意:只有当您通过 Flask 使用 render_template 方法渲染 HTML 文件,或者使用 Flask 作为 Web 服务器时,这才有效。

-2

出于安全考虑,Google Chrome 不允许加载本地资源。对于这个问题有一个简单的解决方案。

1.在vscode中安装live-server插件

2.通过live-server打开html文件

xZidLn.png

不是您要找的答案?浏览标记的其他问题或者问你自己的问题


来自   https://stackoverflow.com/questions/39007243/cannot-open-local-file-chrome-not-allowed-to-load-local-resource