181

Test browser: Version of Chrome: 52.0.2743.116

It is a simple javascript that is to open an image file from local like '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/

Please give me any suitable suggestions.

Dharman
  • 30,962
  • 25
  • 85
  • 135
KBH
  • 1,887
  • 2
  • 11
  • 11
  • 1
    use `` to get access to local reources – dandavis Aug 17 '16 at 22:55
  • I managed to get around this painful 'feature' by moving the image into my wwwroot directory( Same dir that Css and js are stored ) and referring to it as './Img.jpg'. I am using visual studio and C#. – Alan Jan 31 '23 at 16:46

16 Answers16

113

We use Chrome a lot in the classroom and it is a must to working with local files.

What we have been using is "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)

It is a simple server and cannot use PHP but for simple work, might be your solution:

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

Dharman
  • 30,962
  • 25
  • 85
  • 135
Woody
  • 1,449
  • 3
  • 19
  • 27
  • 2
    Woody: thanks a lot! This approach helped me. I run a local Tomcat + a local AWS S3 bucket on Windows 10. Now I can switch between the live AWS server and a local one. Cheers. Q – user1723453 Oct 04 '17 at 15:57
  • 2
    thanks Woody but do you know anything better? it needed to be lunched every time. I want some background passive extension that just enable accessing file:/// – Mohammad_Hosein Jan 21 '21 at 11:34
  • 1
    @Mohammad_Hosein Unfortunately I do not know of an easier chrome plugin. A lot of students use the EasyPHP Dev https://www.easyphp.org/. There is also lite-server for the more technically inclined https://github.com/johnpapa/lite-server | https://www.freecodecamp.org/news/how-you-can-use-lite-server-for-a-simple-development-web-server-33ea527013c9/ – Woody Jan 21 '21 at 20:27
  • Great solution, but I'm not sure it is safe. Using a computer as a server is always a risk, as far as I know. – john c. j. Mar 23 '21 at 01:09
  • 3
    @john-c-j Unless you are allowing access to your local computer there is no harm at all. You are using your computer with a local port. If you expose the local port to the outside world, then you making a HUGE mistake. – Woody Mar 24 '21 at 02:19
  • 1
    For me it didn't work. – Ionut Feb 14 '23 at 11:24
55

1) Open your terminal and type

npm install -g http-server

2) Go to the root folder that you want to serve you files and type:

http-server ./

3) Read the output of the terminal, something kinda http://localhost:8080 will appear.

Everything on there will be allowed to be got. Example:

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

Marcelo
  • 1,486
  • 13
  • 16
  • http-server has an issue now causing errors - you can downgrade it to 0.9 though to fix - see https://stackoverflow.com/questions/56364464/http-server-with-localhost3000-gives-err-invalid-redirect – Brian Burns Oct 28 '19 at 21:57
  • 1
    This was the simplest answer for me. Worked 100%. Thanks! – robrecord Nov 12 '19 at 11:20
  • Windows machine and very locked down. "npm" is definitely not installed nor will it ever be installed. Any software not approved by corporate cyber-security cannot be installed. – mnemotronic Nov 08 '22 at 02:25
  • In a non administrative PowerShell console session I found it useful to skip step 1 and run "npx http-server" instead for step 2 after confirming nodejs was installed. – Chris Smith Nov 29 '22 at 05:20
  • Very easy to do, and works perfectly! Thanks for sharing – justdoingmyjob Aug 08 '23 at 18:54
33

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.

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.

enter image description here

This webpage uses AngularJS 1.x to list the various shortcuts.

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.

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

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

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.

This Handler code loads the file, then passes it's contents back in the HTTP response.

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.

Just one last comment: the original question wanted to open the file "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. So the best you can do is use code like mine to access files somewhere on a network drive.

Mike Gledhill
  • 27,846
  • 7
  • 149
  • 159
  • 1
    Sounds good, but how do you handle authorization (read permissions)? What if not all users are allowed to view a given file? Wouldn't you need to perform the read in the name of the requesting user? – Timi Sep 10 '19 at 08:44
  • Why do you use a webclient to open a local file? And for me, it tries to open C:\SomeNetworkPath\... – Kev Jan 15 '20 at 11:05
  • If we are not using angular is it still possible? – Ahmad.Tr Apr 06 '20 at 22:22
  • This was a useful answer but it would very much effect the load time of the web page if you have hundreds of pictures being rendered and downloaded like this via this ashx handle. – Jamshaid K. May 17 '20 at 05:09
  • I like this answer but I feel like I need to downvote it because this will definitely be copy + pasted by less security conscious developers who are going to unknowingly add a way for anybody to access any file the server has access to. – Marie Mar 09 '21 at 15:54
  • 1
    @Marie - thank you for the feedback. Genuinely, no one's ever had the courtesy to explain why they're downvoting me before, so I do appreciate it. I do agree, it does provide a back-door around Chrome's security, but in my company's in-house app, this solution was needed, and was a lifesaver. But yes, as I said... tread carefully ! – Mike Gledhill Mar 10 '21 at 16:04
18

Chrome specifically blocks local file access this way for security reasons.

Here's an article to workaround the flag in Chrome (and open your system up to vulnerabilities):

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

Scott
  • 21,475
  • 8
  • 43
  • 55
  • 5
    I tried to follow the solution "c:\path\chrome.exe" -allow-file-access-from-files but I cannot open it. Please test this website https://fiddle.jshell.net/q326vLya/3/. What am I doing wrong? – KBH Aug 18 '16 at 15:38
  • 13
    On GoogleChrome 66 its not working. Chrome starts with that flag, but it still shows that local file canbt be opened. – Radon8472 Jun 06 '18 at 14:11
  • 6
    please edit answer. it's not working anymore. – Mohammad_Hosein Jan 21 '21 at 11:38
13

There is a workaround using Web Server for Chrome.
Here are the steps:

  1. Add the Extension to chrome.
  2. Choose the folder (C:\images) and launch the server on your desired port.

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.

Shwetabh Shekhar
  • 2,608
  • 1
  • 23
  • 36
  • thanks. but do you know anything better? it needed to be lunched every time. I want some background passive extension that just enable accessing file:/// – Mohammad_Hosein Jan 21 '21 at 11:39
7

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

$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

Ruberandinda Patience
  • 3,435
  • 3
  • 20
  • 18
4

Google Chrome does not allow to load local resources because of the security. Chrome need http url. Internet Explorer and Edge allows to load local resources, but Safari, Chrome, and Firefox doesn't allows to load local resources.

Go to file location and start the Python Server from there.

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);
}
shah
  • 81
  • 1
  • 6
2

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. 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!).

See also:

Community
  • 1
  • 1
Prak
  • 302
  • 1
  • 9
  • 1
    the reason for the rule is more social than technical; browsers do a good job of preventing programatic access to off-domain resources already (eg. SOP, CDN scripts, deep-linked IMG tags, etc), but it freaks people out to _see_ their local contents in a browser window, even if the script can't tell what it's showing... – dandavis Aug 17 '16 at 23:09
  • 1
    @dandavis yes, you're right, still I believe it can be good to prevent this to happen. Apart from bugs in some implementations (if you cannot open a local resource, you're probably safer), there can be some specific scenarios where other people are looking at your screen (screen-sharing apps, or simply behind your back in your office) and you don't want that your images (potentially a Credit Card or a private image) can be opened just by visiting some websites that can guess the location on your local filesystem... – Prak Aug 17 '16 at 23:55
2

If you have php installed - you can use built-in server. Just open target dir with files and run

php -S localhost:8001
Andrew Zhilin
  • 1,654
  • 16
  • 11
1

You just need to replace all image network paths to byte strings in stored Encoded HTML string. For this you required HtmlAgilityPack to convert Html string to Html document. https://www.nuget.org/packages/HtmlAgilityPack

Find Below code to convert each image src network path(or local path) to byte sting. It will definitely display all images with network path(or local path) in IE,chrome and 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;
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
1

Chrome and other Browser restrict the access of a server to local files due to security reasons. 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 --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.

1

I've encounterd this problem, and here is my solution for Angular, I wrapped my Angular's asset folder in encodeURIComponent() function. 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)

I used Angular 9, so this is my url when I clicked open local file:
```http://localhost:4200/%2Fassets%2Foffice%2Ffile_2.pdf```
wimblywombly
  • 71
  • 1
  • 7
1

This is for google-chrome-extension

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

manifest.json

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

Carson
  • 6,105
  • 2
  • 37
  • 45
0

This solution worked for me in PHP. It opens the PDF in the browser.

// $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);
    }
}
rgoot
  • 48
  • 1
  • 9
0

In the case of audio files, when you give <audio src="C://somePath"/>, this throws an error saying 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.

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

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

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. 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. Hence the audio shows up on 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.

ANUP SAJJAN
  • 1,458
  • 13
  • 17
-2

Google Chrome does not allow to load local resources because of the security . There is a simple solution for this problem .

1.install live-server plugin in vscode

2.open the html file by live-server

xZidLn.png