ローカルファイルを開けません-Chrome:ローカルリソースを読み込めません


99

テストブラウザ:Chromeのバージョン:52.0.2743.116

それは 'C:\ 002.jpg'のようなローカルから画像ファイルを開くシンプルなjavascriptです。

function run(){

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

   window.open(URL, null);

}
run();

これが私のサンプルコードです。 https://fiddle.jshell.net/q326vLya/3/

適切な提案があれば教えてください。


<input type=file>地元のリソースへのアクセスを取得するために使用
dandavis

回答:


62

これは少し古いことですが、このような多くの質問を参照してください...

私たちは教室でChromeを頻繁に使用しており、ローカルファイルでの作業には必須です。

使用しているのは「Webサーバーfor Chrome」です。それを起動し、操作したいフォルダを選択して、URLに移動します(選択した127.0.0.1:portなど)

これは単純なサーバーであり、PHPを使用することはできませんが、単純な作業では、ソリューションになる可能性があります。

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


1
ウッディ:どうもありがとう!このアプローチは私を助けました。Windows 10でローカルTomcat +ローカルAWS S3バケットを実行しています。これで、ライブAWSサーバーとローカルサーバーを切り替えることができます。乾杯。Q
user1723453 2017年

20

わかりました、このエラーメッセージの背後にあるセキュリティ上の理由は完全に理解していますが、回避策が必要な場合もあります... (この質問のベースとなったJavaScriptではなく)ASP.Netを使用しますが、誰かに役立つと思います。

社内アプリには、ユーザーがネットワーク全体に広がる便利なファイルへのショートカットのリストを作成できるWebページがあります。彼らがこれらのショートカットの1つをクリックしたときに、これらのファイルを開きたい...しかし、もちろん、Chromeのエラーが原因でこれを防ぐことができます。

ここに画像の説明を入力してください

このWebページでは、AngularJS 1.xを使用してさまざまなショートカットをリストしています。

もともと、私のWebページは<a href..>ファイルを指す要素を直接作成しようとしNot allowed to load local resourceましたが、ユーザーがこれらのリンクの1つをクリックしたときに「」エラーが発生しました。

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

以上です。

これで、ユーザーが私のショートカットリンクの1つをクリックすると、OpenAnExternalFileこの.ashxファイルを開く関数が呼び出され、開くファイルのパスとファイル名が渡されます。

このハンドラーコードはファイルをロードし、その内容をHTTP応答で返します。

そして、仕事が完了すると、ウェブページは外部ファイルを開きます。

ふew!繰り返しになりますが、Chromeがこの「Not allowed to load local resources」例外をスローする理由があります。これを注意深く読んでください...しかし、これはこの制限を回避するためのかなり簡単な方法であることを示すために、このコードを投稿しています。

最後のコメントは1つだけです。元の質問ではファイル「C:\002.jpg」を開こうとしました。あなたはできませんこれを行います。Webサイトは1つのサーバー(独自のC:ドライブを使用)に配置され、ユーザー独自のC:ドライブに直接アクセスすることはできません。したがって、あなたができる最善のことは、私のようなコードを使用して、ネットワークドライブ上のどこかにあるファイルにアクセスすることです。


良さそうに聞こえますが、承認(読み取り権限)をどのように処理しますか?すべてのユーザーが特定のファイルを表示できるわけではない場合はどうなりますか?要求しているユーザーの名前で読み取りを実行する必要はありませんか?
Timi

なぜWebクライアントを使用してローカルファイルを開くのですか?そして私にとっては、C:\ SomeNetworkPath \ ...を開こうとします
Kev

角度を使用していない場合でも可能ですか?
Ahmad.Tr

これは有用な回答でしたが、このashxハンドルを介してこのように何百もの画像をレンダリングおよびダウンロードすると、Webページのロード時間に大きな影響を与えます。
Jamshaid Kamran

17

Chromeは特に、セキュリティ上の理由から、この方法でローカルファイルアクセスをブロックします。

Chromeでフラグを有効にする(そしてシステムを脆弱性にさらす)ための回避策は次のとおりです。

c:\ Program Files(x86)\ google \ chrome \ Application \ chrome.exe --allow-file-access-from-files


4
ソリューション "c:\ path \ chrome.exe" -allow-file-access-from-filesを実行しようとしましたが、開くことができません。このウェブサイトfiddle.jshell.net/q326vLya/3をテストしてください。何が悪いのですか?
KBH

5
GoogleChrome 66では機能しません。Chromeはそのフラグで始まりますが、それでもローカルファイルを開くことができることを示しています。
Radon8472

16

1)ターミナルを開いて入力します

npm install -g http-server

2)ファイルを提供するルートフォルダーに移動し、次のように入力します。

http-server ./

3)端末の出力を読み取ると、なんらかのhttp://localhost:8080表示が出ます。

そこにあるものはすべて手に入れられるでしょう。例:

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


http-serverにエラーが発生する問題が発生しました-修正するために0.9にダウングレードできます-stackoverflow.com/questions/56364464/…を
Brian Burns

これは私にとって最も簡単な答えでした。100%働いた。ありがとう!
-robrecord

9

Chrome用Webサーバーを使用する回避策があります
手順は次のとおりです。

  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ヘッダーオプションを選択する必要がある場合があります。


5

プロジェクトディレクトリの外部またはユーザーレベルのディレクトリからイメージを読み込むことができないため、「ローカルリソースにアクセスできません」という警告が表示されます。

しかし、ファイルをプロジェクトのルートフォルダーに配置して、次のように{rootFolder}\Content\my-image.jpg参照するとします。

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

4

この問題は、サーバー側の言語としてPHPを使用していて、回避策として、結果をクライアントに送信する前に画像のbase64 encondingを生成することでした。

$path = 'E:/pat/rwanda.png';
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);

私は誰かに彼自身の作品を作成するアイデアを与えるかもしれないと思います

ありがとう


2

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

PHPがインストールされている場合-組み込みサーバーを使用できます。ファイルでターゲットディレクトリを開いて実行するだけです

php -S localhost:8001

1

これを行うことができた場合、ファイルシステムにアクセスでき、そこにあるデータを操作できる可能性があるため、大きなセキュリティ上の問題を引き起こします...幸い、実行しようとしていることを実行することはできません。

ローカルリソースにアクセスする必要がある場合は、マシンでWebサーバーを起動してみてください。この場合、メソッドが機能します。Chromeの設定で動作するなど、他の回避策も可能ですが、私は常にクリーンな方法でローカルWebサーバーを別のポートにインストールすることを好みます(いいえ、それほど難しくありません!)。

以下も参照してください。


ルールの理由は、技術的というより社会的です。ブラウザは、すでにオフドメインのリソース(例えばSOP、CDNスクリプト、ディープリンクIMGタグなど)へのプログラムによるアクセスを防止する良い仕事をするが、それは人々をフリークアウトを参照しても、ブラウザウィンドウに自分のローカルコンテンツをスクリプトは何が表示されているのか
わかり

1
@dandavisはい、そうです、それでも、これを防ぐのは良いことだと思います。一部の実装のバグ(ローカルリソースを開けない場合は、おそらく安全です)とは別に、他の人が画面を見ている特定のシナリオ(画面共有アプリ、または単にオフィスの後ろにいる)が存在する可能性があります)そして、ローカルファイルシステム上の場所を推測できるいくつかのWebサイトにアクセスするだけで、画像(潜在的にはクレジットカードまたはプライベート画像)が開かれることを望まない...
Prak

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;

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

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、サーバー側でレンダリングできるファイル名ごとに異なるルートを作成しました。


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```
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.