5

I'm currently trying to build a "web app" that runs off a flash drive, thus there can't be any other environment requires that launching chrome with some launch options and a path to the index.html file on the flash drive.

I'm having some trouble getting angularJS to play nicely when loading files with the file:// protocol and not through a web server.

I've gotten it to load local resources ( like a video) by setting html5 mode to true but I currently am unable to use the route provider.

Here's what I have: var testApp = angular.module("testApp", ['angular-underscore', "ngRoute", "com.2fdevs.videogular"]);

testApp.config(function($locationProvider, $routeProvider) {
    $locationProvider.html5Mode(true);
  $routeProvider.when('/', {template: '/views/MainView.html', controller: "VideoPlayerController" })
.otherwise({redirectTo:'/'});;
});

Whenever I load up my index.html file in Chrome by double clicking the file, the url starts with as "file://". This also happens when I launch via command line with the essential option "--allow-file-access-from-files".

How do I get the routeProvider to work as intended with file://? It currently isn't recognizing even the "otherwise" route unless I add the following to my head tag in index.html

<base href="/index.html">

But that ends up with

file:///

in the URL field of Chrome. All other resources fail to load. Below is an example of the error I'm seeing with just one controller combo.

GET file:///index.html net::ERR_FILE_NOT_FOUND 

Thanks SO! (I know all my problems would disappear if I was willing to use a webserver but I'm not allowed to on this project at the moment)

bobber205
  • 12,948
  • 27
  • 74
  • 100
  • I am. Why? Does it make a difference? :) – bobber205 Dec 12 '13 at 00:02
  • angular docs say "$route is used for deep-linking URLs". file: protocol is not a url; no queryString, fragments, etc. in short, it might not ever work without patching the angular code... – dandavis Dec 12 '13 at 00:05
  • On http://stackoverflow.com/questions/15677882/angularjs-routing-without-a-web-server someone said "Angular is a client-side JS framework, so it doesn't need a web-server.". hope there is a way indeed! :) – bobber205 Dec 12 '13 at 00:07
  • most of angular does indeed work fine without a server. in a way i had not noticed before, routing does subtly depend on having a server for reasons you've discovered. there might be other snags as well like localStorage/cookie, history, and CSP issues. don't expect full functionality from most browsers when viewing a file; that what everyone bitched about the most when IE5+6 did it... it's tough to make a distribute-able app in single html file. – dandavis Dec 12 '13 at 00:12
  • I may be wrong but how do you want to use **HTML5 mode** without proper redirects? – F Lekschas Dec 12 '13 at 08:49

1 Answers1

7

You can get the Angular side of things to work, by using a dynamic base tag:

<script>document.write('<base href="' + document.location + '" />');</script>

as Plunkr does it. You can then remove the first / from the path to the templates to make them relative to the base, and Angular attempts to fetch the template from the correct location. However you then run up against browser security constraints, at least in Chrome, which treat Ajax requests to file://, even if from file://, as cross-domain.

Barring any changes to the browser security settings, the solution to that is to write (or have some Grunt-type build process to build) the templates right into the JS, so Angular doesn't have to make any Ajax requests. For example

app.run(function($templateCache) {
  $templateCache.put('views/MainView.html', 'In the MainView partial <strong>{{message}}</strong>');
});

I've also found the the HTML5 routing doesn't appear to work with file://, so that must be disabled.

I've constructed a simple plunkr that shows this, that also works when downloaded, at least onto a Mac with Chrome. I've also made a slightly more complicated plunkr, that shows you can navigate between routes like #/ <-> #/inner , when downloaded to a file.

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165
  • I've already added "--allow-file-access-from-files" Is there any other security settings I should set? – bobber205 Dec 12 '13 at 17:45
  • I missed that that: my solution assumes no changes to security settings. Assuming you have "--allow-file-access-from-files", and it allows Ajax requests to the file system, then actually you shouldn't need to have the templates in the JS. In any case, you shouldn't need to change any other security settings. – Michal Charemza Dec 12 '13 at 18:03
  • There's already business requirements to load resources like html5 videos so having that security setting is required. But good to know I shouldn't have to turn anything else on/off. – bobber205 Dec 12 '13 at 18:05
  • I'll be interested to know if you need the allow-file-access-from-files option for html5 video. Other reasources, like images in `img` tags, I think can be injected in the page fine, even when on `file://`. – Michal Charemza Dec 12 '13 at 18:17
  • Ah. I may not be using --allow-file-access-from-files for html5 video after all. Once I find out I'll report back – bobber205 Dec 12 '13 at 18:20