簡體   English   中英

無法打開本地文件 - Chrome:不允許加載本地資源

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

測試瀏覽器: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/

請給我任何合適的建議。

我們在課堂上經常使用 Chrome,因此必須使用本地文件。

我們一直在使用的是“Web Server for Chrome”。 您啟動它,選擇希望使用的文件夾並轉到 URL(例如您選擇的 127.0.0.1:port)

它是一個簡單的服務器,不能使用 PHP,但對於簡單的工作,可能是您的解決方案:

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

1)打開你的終端並輸入

npm install -g http-server

2)轉到您要為您提供文件的根文件夾並鍵入:

http-server ./

3) 閱讀終端的輸出,會出現類似http://localhost:8080內容。

那里的一切都將被允許獲得。 例子:

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

好的,伙計們,我完全理解此錯誤消息背后的安全原因,但有時,我們確實需要一種解決方法......這是我的。 它使用 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: 驅動器。 所以你能做的最好的事情就是使用像我這樣的代碼來訪問網絡驅動器上某處的文件。

出於安全原因,Chrome 專門以這種方式阻止本地文件訪問。

這是一篇解決 Chrome 中的標志的文章(並打開您的系統以應對漏洞):

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

有一個使用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 選項,以防您遇到任何跨源訪問錯誤。

您將無法在項目目錄之外或從用戶級目錄加載圖像,因此“無法訪問本地資源警告”。

但是,如果您要將文件放在項目的根文件夾中,例如{rootFolder}\\Content\\my-image.jpg並像這樣引用它:

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

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

我認為可能會給某人創造自己的工作的想法

謝謝

出於安全考慮,谷歌瀏覽器不允許加載本地資源。 Chrome 需要 http 網址。 Internet Explorer 和 Edge 允許加載本地資源,但 Safari、Chrome 和 Firefox 不允許加載本地資源。

轉到文件位置並從那里啟動 Python 服務器。

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

如果你能做到這一點,這將代表一個很大的安全問題,因為你可以訪問你的文件系統,並可能對那里的可用數據采取行動......幸運的是,你不可能做你想做的事情。

如果您需要訪問本地資源,您可以嘗試在您的機器上啟動一個 Web 服務器,在這種情況下,您的方法將起作用。 其他解決方法也是可能的,例如對 Chrome 設置進行操作,但我總是更喜歡干凈的方式,安裝本地 Web 服務器,也許在不同的端口上(不,這並不難!)。

也可以看看:

如果您安裝了 php - 您可以使用內置服務器。 只需打開帶有文件的目標目錄並運行

php -S localhost:8001

您只需要將所有圖像網絡路徑替換為存儲的編碼 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;

由於安全原因,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 中對我有用。 它會在瀏覽器中打開 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);
    }
}

我遇到過這個問題,這是我的 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```

在音頻文件的情況下,當您提供<audio src="C://somePath"/> ,這會引發錯誤,提示cannot load local resource. 這是有道理的,因為任何網頁都不能簡單地提供本地路徑並訪問您的私人文件。

如果您嘗試使用動態路徑播放音頻,通過 JS 更改src property ,那么這里是使用 Flask 服務器和 HTML 的示例實現。

服務器.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 請求,我們編寫了一個端點,它接受音頻文件名,從本地目錄中讀取它,然后將其返回。 因此音頻顯示在 UI 上。

注意:這僅在您通過flask 使用render_template 方法渲染HTML 文件時有效,或者說,使用flask 作為您的Web 服務器。

這是用於google-chrome-extension

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

清單文件

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM