Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pure Local Single-Page App With AngularJS and its RouteProvider

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)

like image 447
bobber205 Avatar asked Dec 11 '13 23:12

bobber205


1 Answers

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.

like image 165
Michal Charemza Avatar answered Sep 28 '22 10:09

Michal Charemza