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

时间:2016-08-17 22:31:09

标签: javascript jquery google-chrome web window.open

测试浏览器: 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 个答案:

答案 0 :(得分:39)

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

我们在教室中使用Chrome很多,而且必须使用本地文件。

我们一直在使用的是“Web Server for Chrome”。你启动它,选择希望使用的文件夹并转到URL(如你选择的127.0.0.1:port)

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

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

答案 1 :(得分:14)

好的伙计们,我完全理解这个错误消息背后的安全原因,但有时候,我们确实需要一个解决方法......而且这里是我的。它使用的是ASP.Net(而不是JavaScript,这是基于此问题的),但它有望对某人有用。

我们的内部应用程序有一个网页,用户可以在该网页上创建遍布整个网络的有用文件的快捷方式列表。当他们点击其中一个快捷方式时,我们想要打开这些文件...但当然,Chrome的错误会阻止此操作。

enter image description here

此网页使用AngularJS 1.x列出各种快捷方式。

最初,我的网页试图直接创建一个指向文件的<a href..>元素,但这会产生&#34; Not allowed to load local resource&#34;用户点击其中一个链接时出错。

<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的Handler文件,其中包含以下代码:

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文件,并传递我们要打开的文件的路径+文件名。

此Handler代码加载文件,然后将其内容传回HTTP响应中。

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

P!再一次 - Chrome有理由抛出这个&#34; Not allowed to load local resources&#34;例外情况,请谨慎对待......但我发布此代码只是为了证明这是一种相当简单的解决方法。

最后一条评论:原始问题想要打开文件&#34; C:\002.jpg&#34;。你无法这样做。您的网站将位于一台服务器上(使用它自己的C:驱动器)并且无法直接访问您用户自己的C:驱动器。因此,您可以做的最好的事情是使用像我这样的代码来访问网络驱动器上的某些文件。

答案 2 :(得分:12)

出于安全考虑,Chrome会以这种方式专门阻止本地文件访问。

这是一篇解决Chrome标志问题的文章(并打开系统漏洞):

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

答案 3 :(得分:5)

使用Web Server for Chrome有一种解决方法。
以下是步骤:

  1. 将扩展程序添加到chrome。
  2. 选择文件夹(C:\ images)并启动服务器 在你想要的港口。
  3. 现在可以轻松访问您的本地文件:

    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标题选项,如果您遇到任何错误的任何交叉原点访问错误。

答案 4 :(得分:4)

1) 打开您的终端并输入

npm install -g http-server

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

http-server ./

3) 读取终端的输出,将会出现http://localhost:8080

那里的一切都会被允许。 示例:

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

答案 5 :(得分:3)

您无法在项目目录之外或用户级目录中加载图像,因此&#34;无法访问本地资源警告&#34;。

但是如果您要将文件放在项目的根文件夹中,就像在myProject\Content\中一样,并像这样引用它:

<img src="/Content/myfolder/myimage.jpg" />

答案 6 :(得分:2)

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

php -S localhost:8001

答案 7 :(得分:1)

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

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

另见:

答案 8 :(得分:1)

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

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

谢谢

答案 9 :(得分:0)

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

答案 10 :(得分:0)

出于安全考虑,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);
}

答案 11 :(得分: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);
    }
}

答案 12 :(得分:0)

我遇到了这个问题,这是我对Angular的解决方案,我将Angular的资产文件夹包装在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```

答案 13 :(得分:0)

在音频文件的情况下,当您提供 <audio src="C://somePath"/> 时,这会引发错误,提示 cannot load local resource. 这是有道理的,因为任何网页都不能简单地提供本地路径并访问您的私人文件。

如果您尝试通过 JS 更改 src property 来使用动态路径播放音频,那么这里是使用 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")
<块引用>

audioMap.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 请求,我们编写了一个端点,它接受音频文件名,从本地目录中读取它,然后将其返回。因此音频会显示在 UI 上。

<块引用>

注意:这仅在您使用 通过flask 的render_template 方法,或者说,使用flask 作为您的网络服务器。

答案 14 :(得分:0)

这是给google-chrome-extension

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

manifest.json

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

答案 15 :(得分:-1)

由于安全原因,Chrome和其他浏览器将服务器的访问限制为本地文件。但是,您可以在允许的访问模式下打开浏览器。只需打开终端并转到chrome.exe的存储文件夹,然后输入以下命令即可。

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

Read this for more details

但是,这种方式对我不起作用,因此我为特定目录中的每个文件设置了不同的路由。因此,转到该路径意味着打开该文件。

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

我调用此函数来传递目录__dirname/public/extracted中的文件名列表,它为我能够在服务器端呈现的每个文件名创建了一条不同的路由。