简体   繁体   English

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

[英]Cannot open local file - Chrome: Not allowed to load local resource

Test browser: Version of Chrome: 52.0.2743.116测试浏览器:Chrome 版本:52.0.2743.116

It is a simple javascript that is to open an image file from local like 'C:\002.jpg'它是一个简单的 javascript,它是从本地打开一个图像文件,如 'C:\002.jpg'

function run(){

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

   window.open(URL, null);

}
run();

Here is my sample code.这是我的示例代码。 https://fiddle.jshell.net/q326vLya/3/ https://fiddle.jshell.net/q326vLya/3/

Please give me any suitable suggestions.请给我任何合适的建议。

We use Chrome a lot in the classroom and it is a must to working with local files.我们在课堂上经常使用 Chrome,因此必须使用本地文件。

What we have been using is "Web Server for Chrome".我们一直在使用的是“Web Server for Chrome”。 You start it up, choose the folder wishing to work with and go to URL (like 127.0.0.1:port you chose)您启动它,选择希望使用的文件夹并转到 URL(例如您选择的 127.0.0.1:port)

It is a simple server and cannot use PHP but for simple work, might be your solution:它是一个简单的服务器,不能使用 PHP,但对于简单的工作,可能是您的解决方案:

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

1) Open your terminal and type 1)打开你的终端并输入

npm install -g http-server

2) Go to the root folder that you want to serve you files and type: 2)转到您要为您提供文件的根文件夹并键入:

http-server ./

3) Read the output of the terminal, something kinda http://localhost:8080 will appear. 3) 阅读终端的输出,会出现类似http://localhost:8080内容。

Everything on there will be allowed to be got.那里的一切都将被允许获得。 Example:例子:

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

Okay folks, I completely understand the security reasons behind this error message, but sometimes, we do need a workaround... and here's mine.好的,伙计们,我完全理解此错误消息背后的安全原因,但有时,我们确实需要一种解决方法......这是我的。 It uses ASP.Net (rather than JavaScript, which this question was based on) but it'll hopefully be useful to someone.它使用 ASP.Net(而不是这个问题所基于的 JavaScript),但它希望对某人有用。

Our in-house app has a webpage where users can create a list of shortcuts to useful files spread throughout our network.我们的内部应用程序有一个网页,用户可以在其中创建一个快捷方式列表,这些文件指向遍布我们网络的有用文件。 When they click on one of these shortcuts, we want to open these files... but of course, Chrome's error prevents this.当他们点击这些快捷方式之一时,我们想要打开这些文件……但当然,Chrome 的错误阻止了这一点。

在此处输入图片说明

This webpage uses AngularJS 1.x to list the various shortcuts.本网页使用 AngularJS 1.x 来列出各种快捷方式。

Originally, my webpage was attempting to directly create an <a href..> element pointing at the files, but this produced the " Not allowed to load local resource " error when a user clicked on one of these links.最初,我的网页试图直接创建一个指向文件的<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>

The solution was to replace those <a href..> elements with this code, to call a function in my Angular controller...解决方案是用此代码替换那些<a href..>元素,以在我的 Angular 控制器中调用一个函数......

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

The function itself is very 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);
}

And in my ASP.Net project, I added a Handler file called DownloadExternalFile.aspx which contained this code:在我的 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;
            }
        }
    }

And that's it.就是这样。

Now, when a user clicks on one of my Shortcut links, it calls the OpenAnExternalFile function, which opens this .ashx file, passing it the path+filename of the file we want to open.现在,当用户单击我的快捷方式链接之一时,它会调用OpenAnExternalFile函数,该函数会打开这个 .ashx 文件,并将我们要打开的文件的路径+文件名传递给它。

This Handler code loads the file, then passes it's contents back in the HTTP response.此处理程序代码加载文件,然后在 HTTP 响应中将其内容传回。

And, job done, the webpage opens the external file.并且,工作完成,网页打开外部文件。

Phew !呼! Again - there is a reason why Chrome throws this " Not allowed to load local resources " exception, so tread carefully with this... but I'm posting this code just to demonstrate that this is a fairly simple way around this limitation.同样 - Chrome 抛出这个“ Not allowed to load local resources ”异常是有原因的,所以请谨慎对待这个......但我发布这段代码只是为了证明这是绕过这个限制的一种相当简单的方法。

Just one last comment: the original question wanted to open the file " C:\\002.jpg ".只有最后一个评论:原来的问题想打开文件“ C:\\002.jpg ”。 You can't do this.不能这样做。 Your website will sit on one server (with it's own C: drive) and has no direct access to your user's own C: drive.您的网站将位于一台服务器上(使用它自己的 C: 驱动器)并且无法直接访问您用户自己的 C: 驱动器。 So the best you can do is use code like mine to access files somewhere on a network drive.所以你能做的最好的事情就是使用像我这样的代码来访问网络驱动器上某处的文件。

Chrome specifically blocks local file access this way for security reasons.出于安全原因,Chrome 专门以这种方式阻止本地文件访问。

Here's an article to workaround the flag in Chrome (and open your system up to vulnerabilities):这是一篇解决 Chrome 中的标志的文章(并打开您的系统以应对漏洞):

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

There is a workaround using Web Server for Chrome .有一个使用Web Server for Chrome的解决方法。
Here are the steps:以下是步骤:

  1. Add the Extension to chrome.将扩展添加到 chrome。
  2. Choose the folder (C:\\images) and launch the server on your desired port.选择文件夹(C:\\images)并在所需端口上启动服务器。

Now easily access your local file:现在轻松访问您的本地文件:

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: You might need to select the CORS Header option from advanced setting incase you face any cross origin access error. PS:您可能需要从高级设置中选择 CORS Header 选项,以防您遇到任何跨源访问错误。

You won't be able to load an image outside of the project directory or from a user level directory, hence the "cannot access local resource warning".您将无法在项目目录之外或从用户级目录加载图像,因此“无法访问本地资源警告”。

But if you were to place the file in a root folder of your project like in {rootFolder}\\Content\\my-image.jpg and referenced it like so:但是,如果您要将文件放在项目的根文件夹中,例如{rootFolder}\\Content\\my-image.jpg并像这样引用它:

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

This issue come when I am using PHP as server side language and the work around was to generate base64 enconding of my image before sending the result to client当我使用 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);

I think may give someone idea to create his own work around我认为可能会给某人创造自己的工作的想法

Thanks谢谢

Google Chrome does not allow to load local resources because of the security.出于安全考虑,谷歌浏览器不允许加载本地资源。 Chrome need http url. Chrome 需要 http 网址。 Internet Explorer and Edge allows to load local resources, but Safari, Chrome, and Firefox doesn't allows to load local resources. Internet Explorer 和 Edge 允许加载本地资源,但 Safari、Chrome 和 Firefox 不允许加载本地资源。

Go to file location and start the Python Server from there.转到文件位置并从那里启动 Python 服务器。

python -m SimpleHttpServer

then put that url into function:然后将该网址放入函数中:

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

If you could do this, it will represent a big security problem, as you can access your filesystem, and potentially act on the data available there... Luckily it's not possible to do what you're trying to do.如果你能做到这一点,这将代表一个很大的安全问题,因为你可以访问你的文件系统,并可能对那里的可用数据采取行动......幸运的是,你不可能做你想做的事情。

If you need local resources to be accessed, you can try to start a web server on your machine, and in this case your method will work.如果您需要访问本地资源,您可以尝试在您的机器上启动一个 Web 服务器,在这种情况下,您的方法将起作用。 Other workarounds are possible, such as acting on Chrome settings, but I always prefer the clean way, installing a local web server, maybe on a different port (no, it's not so difficult!).其他解决方法也是可能的,例如对 Chrome 设置进行操作,但我总是更喜欢干净的方式,安装本地 Web 服务器,也许在不同的端口上(不,这并不难!)。

See also:也可以看看:

If you have php installed - you can use built-in server.如果您安装了 php - 您可以使用内置服务器。 Just open target dir with files and run只需打开带有文件的目标目录并运行

php -S localhost:8001

You just need to replace all image network paths to byte strings in stored Encoded HTML string.您只需要将所有图像网络路径替换为存储的编码 HTML 字符串中的字节字符串。 For this you required HtmlAgilityPack to convert Html string to Html document.为此,您需要 HtmlAgilityPack 将 Html 字符串转换为 Html 文档。 https://www.nuget.org/packages/HtmlAgilityPack https://www.nuget.org/packages/HtmlAgilityPack

Find Below code to convert each image src network path(or local path) to byte sting.查找下面的代码将每个图像 src 网络路径(或本地路径)转换为字节串。 It will definitely display all images with network path(or local path) in IE,chrome and firefox.它肯定会在 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;

Chrome and other Browser restrict the access of a server to local files due to security reasons.由于安全原因,Chrome 和其他浏览器限制服务器访问本地文件。 However you can open the browser in allowed access mode.但是,您可以在允许访问模式下打开浏览器。 Just open the terminal and go to the folder where chrome.exe is stored and write the following command.只需打开终端并转到存储 chrome.exe 的文件夹并编写以下命令。

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

Read this for more details阅读本文了解更多详情

This way, However, didn't work for me so I made a different route for every file in a particular directory.但是,这种方式对我不起作用,因此我为特定目录中的每个文件制作了不同的路由。 Therefore, going to that path meant opening that file.因此,转到该路径意味着打开该文件。

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

I called this function passing the list of filename in the directory __dirname/public/extracted and it created a different route for each filename which I was able to render on server side.我调用了这个函数,传递了目录__dirname/public/extracted中的文件名列表,它为我能够在服务器端呈现的每个文件名创建了一个不同的路由。

This solution worked for me in PHP.这个解决方案在 PHP 中对我有用。 It opens the PDF in the browser.它会在浏览器中打开 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);
    }
}

I've encounterd this problem, and here is my solution for Angular, I wrapped my Angular's asset folder in encodeURIComponent() function.我遇到过这个问题,这是我的 Angular 解决方案,我将 Angular 的资产文件夹包装在 encodeURIComponent() 函数中。 It worked.有效。 But still, I'd like to know more about the risk of this solution if there's any:但是,如果有的话,我想更多地了解此解决方案的风险:

```const URL = ${encodeURIComponent( /assets/office/file_2.pdf )} window.open(URL) ```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```

In the case of audio files, when you give <audio src="C://somePath"/> , this throws an error saying cannot load local resource.在音频文件的情况下,当您提供<audio src="C://somePath"/> ,这会引发错误,提示cannot load local resource. This makes sense because any webpage can't simply give a local path and access your private files.这是有道理的,因为任何网页都不能简单地提供本地路径并访问您的私人文件。

In case you are trying to play audio with dynamic paths, by changing src property through JS, then here is a sample implementation using Flask server and HTML.如果您尝试使用动态路径播放音频,通过 JS 更改src property ,那么这里是使用 Flask 服务器和 HTML 的示例实现。

server.py服务器.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音频地图.html

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

Explanation:解释:

When you give the audio file name under src property, this creates a get request in the flask as shown当您在src属性下提供音频文件名时,这会在烧瓶中创建一个获取请求,如图所示

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

As you can see that, the flask has sent a Get request for the Std.mp3 file.如您所见,flask 已发送了对Std.mp3文件的 Get 请求。 So to serve this get request, we wrote an endpoint that takes the audio file name, reads it from the local directory, and returns it back.因此,为了处理这个 get 请求,我们编写了一个端点,它接受音频文件名,从本地目录中读取它,然后将其返回。 Hence the audio shows up on UI.因此音频显示在 UI 上。

Note: This works only if you are rendering your HTML file using the render_template method via flask or to say, using flask as your web server.注意:这仅在您通过flask 使用render_template 方法渲染HTML 文件时有效,或者说,使用flask 作为您的Web 服务器。

This is for google-chrome-extension这是用于google-chrome-extension

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

manifest.json 清单文件

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM