Yerel dosya açılamıyor - Chrome: Yerel kaynak yüklemesine izin verilmiyor


111

Test tarayıcısı: Chrome Sürümü: 52.0.2743.116

Yerelden 'C: \ 002.jpg' gibi bir resim dosyasını açmak için basit bir javascript.

function run(){

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

   window.open(URL, null);

}
run();

İşte örnek kodum. https://fiddle.jshell.net/q326vLya/3/

Lütfen bana uygun önerilerde bulunun.


kullanmak <input type=file>yerel enerji kaynaklarını erişmek için
dandavis

Yanıtlar:


69

Bunun biraz eski olduğunu bilin, ancak bunun gibi birçok soruyu görün ...

Chrome'u sınıfta çok kullanıyoruz ve yerel dosyalarla çalışmak bir zorunluluktur.

Kullandığımız şey "Chrome için Web Sunucusu". Başlatın, çalışmak istediğiniz klasörü seçin ve URL'ye gidin (127.0.0.1: seçtiğiniz port gibi)

Basit bir sunucudur ve PHP'yi kullanamaz, ancak basit çalışma için çözümünüz olabilir:

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


1
Woody: çok teşekkürler! Bu yaklaşım bana yardımcı oldu. Windows 10'da yerel bir Tomcat + yerel bir AWS S3 klasörü çalıştırıyorum. Artık canlı AWS sunucusu ile yerel sunucu arasında geçiş yapabilirim. Şerefe. Q
user1723453

20

Tamam millet, bu hata mesajının arkasındaki güvenlik nedenlerini tamamen anlıyorum, ancak bazen bir geçici çözüme ihtiyacımız var ... ve işte benimki. ASP.Net kullanıyor (bu sorunun temel aldığı JavaScript yerine) ama umarım birisi için faydalı olacaktır.

Şirket içi uygulamamız, kullanıcıların ağımıza yayılmış yararlı dosyalar için bir kısayol listesi oluşturabilecekleri bir web sayfasına sahiptir. Bu kısayollardan birine tıkladıklarında, bu dosyaları açmak istiyoruz ... ama tabii ki Chrome'un hatası bunu engelliyor.

görüntü açıklamasını buraya girin

Bu web sayfası, çeşitli kısayolları listelemek için AngularJS 1.x kullanır.

Başlangıçta, web sayfam <a href..>dosyaları işaret eden bir öğeyi doğrudan oluşturmaya çalışıyordu , ancak bu Not allowed to load local resource, bir kullanıcı bu bağlantılardan birini tıkladığında " " hata oluşturdu.

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

Çözüm, bu <a href..>öğeleri bu kodla değiştirmek , Angular denetleyicimde bir işlev çağırmaktı ...

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

İşlevin kendisi çok basit ...

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

Ve ASP.Net projemde, DownloadExternalFile.aspxşu kodu içeren bir İşleyici dosyası ekledim :

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

Ve bu kadar.

Şimdi, bir kullanıcı Kısayol bağlantılarımdan birine tıkladığında, OpenAnExternalFilebu .ashx dosyasını açan, açmak istediğimiz dosyanın yolunu + dosya adını ileten işlevi çağırır .

Bu İşleyici kodu dosyayı yükler, ardından içeriğini HTTP yanıtına geri gönderir.

Ve iş bittiğinde web sayfası harici dosyayı açar.

Vay be! Yine - Chrome'un bu " Not allowed to load local resources" istisnayı " " atmasının bir nedeni var, bu yüzden dikkatli davranın ... ancak bu kodu, bu sınırlamayı aşmanın oldukça basit bir yolu olduğunu göstermek için gönderiyorum.

Son bir yorum: asıl soru " C:\002.jpg" dosyasını açmak istedi . Bunu yapamazsınız . Web siteniz tek bir sunucuya (kendi C: sürücüsüne sahip) oturacak ve kullanıcınızın kendi C: sürücüsüne doğrudan erişimi olmayacak. Dolayısıyla, yapabileceğiniz en iyi şey, bir ağ sürücüsündeki dosyalara erişmek için benimki gibi bir kod kullanmaktır.


Kulağa hoş geliyor, ancak yetkilendirmeyi nasıl yönetiyorsunuz (okuma izinleri)? Ya tüm kullanıcıların belirli bir dosyayı görüntülemesine izin verilmiyorsa? Okumayı talep eden kullanıcının adına yapmanız gerekmez mi?
Timi

Yerel bir dosyayı açmak için neden bir web istemcisi kullanıyorsunuz? Ve benim için C: \ SomeNetworkPath \ ...
Kev

Açısal kullanmıyorsak yine de mümkün mü?
Ahmad.Tr

Bu yararlı bir cevaptı, ancak bu ashx tutamacıyla bu şekilde oluşturulan ve indirilen yüzlerce fotoğrafınız varsa, web sayfasının yükleme süresini büyük ölçüde etkiler.
Jamshaid K.

18

1) Terminalinizi açın ve yazın

npm install -g http-server

2) Size dosya sunmak istediğiniz kök klasöre gidin ve şunu yazın:

http-server ./

3) Terminalin çıktısını okuyun, bir çeşit http://localhost:8080görünecektir.

Oradaki her şeyin alınmasına izin verilecek. Misal:

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


http sunucusunda şu anda hatalara neden olan bir sorun var - düzeltmek için bunu 0,9'a düşürebilirsiniz - bkz. stackoverflow.com/questions/56364464/…
Brian Burns

Bu benim için en basit cevaptı. % 100 çalıştı. Teşekkürler!
robrecord

17

Chrome, güvenlik nedeniyle bu şekilde yerel dosya erişimini özellikle engeller.

İşte bayrağı Chrome'da etkinleştirmek (ve sisteminizi güvenlik açıklarına açmak) için bir geçici çözüm:

c: \ Program Files (x86) \ google \ chrome \ Application \ chrome.exe - dosyalardan-izin-dosya-erişimi


5
"C: \ path \ chrome.exe" -allow-file-access-from-files çözümünü izlemeye çalıştım ancak açamıyorum. Lütfen bu web sitesini test edin fiddle.jshell.net/q326vLya/3 . Neyi yanlış yapıyorum?
KBH

9
GoogleChrome 66'da çalışmıyor. Chrome bu bayrakla başlar, ancak yine de yerel dosyanın açılamadığını gösterir.
Radon8472

9

Chrome için Web Sunucusunu kullanan bir geçici çözüm var .
İşte adımlar:

  1. Uzantıyı chrome'a ​​ekleyin.
  2. Klasörü seçin (C: \ images) ve sunucuyu istediğiniz bağlantı noktasında başlatın.

Şimdi yerel dosyanıza kolayca erişin:

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

Not: Herhangi bir çapraz kaynak erişim hatasıyla karşılaşmanız durumunda gelişmiş ayarlardan CORS Başlığı seçeneğini seçmeniz gerekebilir.


6

Proje dizininin dışından veya kullanıcı düzeyindeki bir dizinden görüntü yükleyemezsiniz, bu nedenle "yerel kaynaklara erişilemiyor uyarısı".

Ancak, dosyayı projenizin bir kök klasörüne yerleştirirseniz {rootFolder}\Content\my-image.jpgve bu şekilde referans verirseniz :

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

5

Bu sorun, PHP'yi sunucu tarafı dili olarak kullandığımda ortaya çıkıyor ve çözüm, sonucu istemciye göndermeden önce resmimin base64 kodlamasını oluşturmaktı

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

Sanırım birisine kendi çalışmasını etrafında yaratması için fikir verebilir

Teşekkürler


2

Google Chrome, güvenlik nedeniyle yerel kaynakları yüklemeye izin vermiyor. Chrome'un http url'ye ihtiyacı var. Internet Explorer ve Edge yerel kaynakları yüklemeye izin verir, ancak Safari, Chrome ve Firefox yerel kaynakları yüklemeye izin vermez.

Dosya konumuna gidin ve oradan Python Sunucusunu başlatın.

python -m SimpleHttpServer

sonra bu url'yi işlevine koyun:

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

Eğer php yüklediyseniz - yerleşik sunucuyu kullanabilirsiniz. Sadece hedef dizini dosyalarla açın ve çalıştırın

php -S localhost:8001

1

Bunu yapabilirseniz, dosya sisteminize erişebileceğiniz ve potansiyel olarak orada bulunan verilere göre hareket edebileceğiniz için bu büyük bir güvenlik sorununu temsil eder ... Neyse ki yapmaya çalıştığınız şeyi yapmak mümkün değildir.

Erişilecek yerel kaynaklara ihtiyacınız varsa, makinenizde bir web sunucusu başlatmayı deneyebilirsiniz ve bu durumda yönteminiz işe yarayacaktır. Chrome ayarlarına göre hareket etmek gibi başka geçici çözümler de mümkündür, ancak her zaman temiz yolu tercih ederim, yerel bir web sunucusu kurmayı, belki de farklı bir bağlantı noktasına (hayır, o kadar zor değil!).

Ayrıca bakınız:


kuralın nedeni teknikten çok sosyaldir; tarayıcılar zaten alan dışı kaynaklara programatik erişimi engelleme konusunda iyi bir iş çıkarıyor (örn. SOP, CDN komut dosyaları, derin bağlantılı IMG etiketleri, vb.), ancak insanları yerel içeriklerini bir tarayıcı penceresinde görmeye korkutuyor . komut dosyası ne gösterdiğini
anlayamıyor

1
@dandavis evet, haklısınız, yine de bunun olmasını önlemenin iyi olabileceğine inanıyorum. Bazı uygulamalardaki hataların yanı sıra (yerel bir kaynağı açamazsanız, muhtemelen daha güvendesinizdir), başkalarının ekranınıza baktığı bazı özel senaryolar olabilir (ekran paylaşım uygulamaları veya sadece ofisinizde arkanızdan) ) ve resimlerinizin (potansiyel olarak bir Kredi Kartı veya özel bir resim), yerel dosya sisteminizdeki konumu tahmin edebilen bazı web sitelerini ziyaret ederek açılmasını
istemezsiniz

1

Tüm görüntü ağ yollarını, depolanan Kodlanmış HTML dizesindeki bayt dizelerine değiştirmeniz yeterlidir. Bunun için Html dizesini Html belgesine dönüştürmek için HtmlAgilityPack'e ihtiyacınız vardı. https://www.nuget.org/packages/HtmlAgilityPack

Her bir görüntü src ağ yolunu (veya yerel yolu) bayt iğnesine dönüştürmek için aşağıdaki kodu bulun. IE, chrome ve firefox'ta ağ yolu (veya yerel yol) ile tüm görüntüleri kesinlikle gösterecektir.

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;

1

Chrome ve diğer Tarayıcı, güvenlik nedeniyle bir sunucunun yerel dosyalara erişimini kısıtlar. Ancak tarayıcıyı izin verilen erişim modunda açabilirsiniz. Sadece terminali açın ve chrome.exe'nin depolandığı klasöre gidin ve aşağıdaki komutu yazın.

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

Daha fazla ayrıntı için bunu okuyun

Ancak bu şekilde benim için işe yaramadı, bu yüzden belirli bir dizindeki her dosya için farklı bir rota yaptım. Bu nedenle, o yola gitmek o dosyayı açmak anlamına geliyordu.

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

Bu işlevi dizindeki dosya adı listesini geçirerek çağırdım __dirname/public/extractedve sunucu tarafında işleyebildiğim her dosya adı için farklı bir yol oluşturdu.


0

Bu çözüm PHP'de benim için çalıştı. PDF'yi tarayıcıda açar.

// $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

Bu sorunla karşılaştım ve işte Angular için çözümüm, Angular'ımın varlık klasörünü encodeURIComponent () işlevine sardım. İşe yaradı. Yine de, varsa bu çözümün riski hakkında daha fazla bilgi edinmek istiyorum:

`` `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```
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.