Sergey Romanov
Sergey Romanov

Reputation: 3080

How to load my angular app correctly with electron throu file:///?

I have a simple Angular app and it is in www folder of my project. It works ok in browser when I run it through http:// server or virtual host. But index.js loads this as file

mainWindow.loadUrl('file://' + __dirname + '/www/index.html'); 

So when I pun electron . it shows blank window. I tried to open my index.html in a Chrome browser through file:/// and it is also blank. The error in console

XMLHttpRequest cannot load file:///Users/Sergey/Sites/Electron-test/www/partials/layout.html. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.(anonymous function) @ angular.js:10722

This is because on router ui

$stateProvider.state("app", {
    url: '/',
    templateUrl: 'partials/layout.html'
});

There are some other same errors for images.

I guess there are 2 solutions to that.

  1. Run server with node and change loadUrl('file:///...') to loadUrl('http:///...') but I have no idea how to do that.
  2. Do something else. May be some header or parameter to allow cross origin requests and I have no idea how to do that.

How can I solve this problem?

Upvotes: 4

Views: 3469

Answers (1)

Sergey Romanov
Sergey Romanov

Reputation: 3080

After some time i have figured out how to do this and now Electron builds app and it runs perfectly. Here is the whole index.js consumed by electron as starting point.

'use strict';
var http = require('http');
var path = require('path');
var fs = require('fs');
var app = require('app');
var BrowserWindow = require('browser-window');

require('crash-reporter').start();

var mainWindow = null;

app.on('window-all-closed', function() {
    if(process.platform != 'darwin') {
        app.quit();
    }
});

app.on('ready', function() {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600
    });

    var server = http.createServer(requestHandler).listen(9527);

    mainWindow.loadUrl('http://localhost:9527/index.html');
    mainWindow.webContents.on('did-finish-load', function() {
        mainWindow.setTitle(app.getName());
    });
    mainWindow.on('closed', function() {
        mainWindow = null;
        server.close();
    });
});

function requestHandler(req, res) {
    var
        file    = req.url == '/' ? '/index.html' : req.url,
        root    = __dirname + '/www',
        page404 = root + '/404.html';

    getFile((root + file), res, page404);
};

function getFile(filePath, res, page404) {

    fs.exists(filePath, function(exists) {
        if(exists) {
            fs.readFile(filePath, function(err, contents) {
                if(!err) {
                    res.end(contents);
                } else {
                    console.dir(err);
                }
            });
        } else {
            fs.readFile(page404, function(err, contents) {
                if(!err) {
                    res.writeHead(404, {'Content-Type': 'text/html'});
                    res.end(contents);
                } else {
                    console.dir(err);
                }
            });
        }
    });
};

This is a starting point. All you have to do is change root parameter to indicate your index.html root folder. But I am sure if you build universal app, it is going to be www.

Upvotes: 6

Related Questions