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

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

请给我任何合适的建议。

732541 次浏览

如果您可以做到这一点,那么它将代表一个大的安全问题,因为您可以访问您的文件系统,并且可能对那里可用的数据进行操作... ... 幸运的是,不可能完成您正在尝试做的事情。

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

参见:

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

这里有一篇文章来解决 Chrome 中的标志问题(并让你的系统暴露漏洞) :

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

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

我们的内部应用程序有一个网页,用户可以创建一个快捷方式列表,有用的文件传播整个网络。当他们点击其中一个快捷方式时,我们希望打开这些文件... ... 当然,Chrome 的错误阻止了这一点。

enter image description here

这个网页使用 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..>元素,在我的角度控制器中调用一个函数..。

<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 文件,将要打开的文件的路径 + 文件名传递给它。

此处理程序代码加载文件,然后将其内容传递回 HTTP 响应中。

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

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

最后一个注释: 最初的问题想要打开文件“ C:\002.jpg”。你 不行这样做。您的网站将坐落在一个服务器(与自己的 C: 驱动器) ,并没有直接访问您的用户自己的 C: 驱动器。所以最好的办法就是使用我的代码来访问网络驱动器上的某个文件。

我们在课堂上经常使用 Chrome,而且必须使用本地文件。

我们一直在使用的是“针对 Chrome 的 Web 服务器”。你启动它,选择希望工作的文件夹,然后转到 URL (像127.0.0.1: 你选择的端口)

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

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

有一个使用 Chrome 网络服务器的变通方法。 < br > 下面是步骤:

  1. 添加扩展到 chrome。
  2. 选择文件夹 (C: 图片)并启动服务器 在你想要的港口。

现在可以轻松访问本地文件:

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

1) 打开终端并输入

npm install -g http-server

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

http-server ./

3) 读取终端的输出,会出现某种类型的 http://localhost:8080

上面所有的东西都可以拿到。 例如:

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

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

我认为可以给某人创作自己的作品的灵感

谢谢

您只需将所有图像网络路径替换为存储的编码 HTML 字符串中的字节字符串。 为此,需要 HtmlAgilityPack 将 Html 字符串转换为 Html 文档。 Https://www.nuget.org/packages/htmlagilitypack

查找以下代码将每个图像 src 网络路径(或本地路径)转换为字节串。 它肯定会显示所有的图像与网络路径(或本地路径)在 IE,铬和火狐。

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 不允许加载本地资源。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);
}

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

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

如果你已经安装了 php-你可以使用内置的服务器。只要打开目标目录和文件运行

php -S localhost:8001

我遇到过这个问题,这里是我对 Angular 的解决方案,我将 Angular 的资产文件夹包装在 encodeURIComponent ()函数中。成功了。但是,我仍然想知道更多关于这个解决方案的风险,如果有的话:

”‘ const URL = ${encodeURIComponent(/asset/office/file _ 2. pdf)} 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```

对于音频文件,当您给出 <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")

视频地图

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

说明:

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

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

正如您所看到的,烧瓶已经发送了一个获取 Std.mp3文件的请求。因此,为了满足这个 get 请求,我们编写了一个端点,该端点接受音频文件名,从本地目录读取它,然后返回它。因此,音频显示在 UI 上。

注意: 只有在使用 Render _ template 方法通过烧瓶或者说,使用烧瓶作为你的 web 服务器。

这是 Google-chrome-扩展

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

宣言 Json

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


由于安全问题,谷歌 Chrome 不允许加载本地资源。 这个问题有一个简单的解决办法。

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

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

xZidLn.png