Skip to content

Instantly share code, notes, and snippets.

@derekchiang
Forked from bellbind/app.html
Last active Jan 19, 2023
Embed
What would you like to do?
[electron]Use electron as a Web Server
<!doctype html>
<html><head><script src="app.js"></script></head><body></body></html>
// utility
var console = {
log: function () {
var ipc = require('electron').ipcRenderer
var args = ["console"].concat([].slice.call(arguments));
return ipc.sendSync.apply(ipc, args)[0];
}
};
var quit = function () {
var ipc = require('electron').ipcRenderer
return ipc.sendSync("app", "quit")[0];
};
// server handler
window.addEventListener("load", function () {
var ipc = require('electron').ipcRenderer
ipc.on("request", function (event, req, port) {
var doc = document.implementation.createHTMLDocument(req.url);
var h1 = doc.createElement("h1");
h1.textContent = "Hello DOM: " + req.url;
doc.body.appendChild(h1);
ipc.send(port, 200, {"content-type": "text/html;charset=UTF-8"},
doc.documentElement.outerHTML);
});
}, false);
const {app, BrowserWindow} = require('electron')
// electron main
console.log(process.versions);
app.on("ready", function () {
var ipc = require('electron').ipcMain
ipc.on("console", function (ev) {
var args = [].slice.call(arguments, 1);
var r = console.log.apply(console, args);
ev.returnValue = [r];
});
ipc.on("app", function (ev, msg) {
var args = [].slice.call(arguments, 2);
ev.returnValue = [app[msg].apply(app, args)];
});
var window = new BrowserWindow({show: false});
window.loadURL("file://" + __dirname + "/app.html");
window.webContents.once("did-finish-load", function () {
var http = require("http");
var crypto = require("crypto");
var server = http.createServer(function (req, res) {
var port = crypto.randomBytes(16).toString("hex");
ipc.once(port, function (ev, status, head, body) {
res.writeHead(status, head);
res.end(body);
});
window.webContents.send("request", req, port);
});
server.listen(8000);
console.log("http://localhost:8000/");
});
});
@derekchiang
Copy link
Author

derekchiang commented Dec 21, 2017

Run electron server.js (or run with xvfb-run as xvfb-run electron server.js on headless linux).

Now visit http://localhost:8000 and http://localhost:8000/foo/bar

@CyprusGrunumn
Copy link

So Im relatively new to Electron and JS as a whole.

if im understanding this correctly, /foo/bar would be a directory on your webserver. so could i instead say

localhost:8000/index.html/

will that return a different web page?

@dirkk0
Copy link

dirkk0 commented Apr 5, 2019

No, it won't - the code above sends the same response to all requests.

If you only need a simple REST-like service, this code is enough:

const { app, BrowserWindow } = require('electron')
const PORT = 8080

// electron main
console.log(process.versions);

app.on("ready", function () {
  var mainWindow = new BrowserWindow({ show: true });
  mainWindow.loadURL("file://" + __static + "/app.html");
  mainWindow.webContents.openDevTools()
  mainWindow.webContents.once("did-finish-load", function () {
    var http = require("http");
    var server = http.createServer(function (req, res) {
      console.log(req.url)
      if (req.url == '/123') {
        res.end(`ah, you send 123.`);
      } else {
        const remoteAddress = res.socket.remoteAddress;
        const remotePort = res.socket.remotePort;
        res.end(`Your IP address is ${remoteAddress} and your source port is ${remotePort}.`);  
      }
    });
    server.listen(PORT);
    console.log("http://localhost:"+PORT);
  });
});

The contents of app.html could be anything.

@Piterden
Copy link

Piterden commented Jan 24, 2021

Ahahaha. The most funny stuff I've seen in last year. @derekchiang did you hear about the technique of caching objects received with require function into variables?

And did you, @dirkk0 hear about the ability of defining languages to code blocks?

@draeder
Copy link

draeder commented Feb 14, 2022

@dirkk0 The version you show completely removes the security features IPC brings to the table.

@haoxi911
Copy link

haoxi911 commented May 2, 2022

@draeder Why is that? It is a local server and only handles certain RESTful URLs. Can you explain a little bit?

The version you show completely removes the security features IPC brings to the table.

@curlyz
Copy link

curlyz commented Jun 29, 2022

@draeder Why is that? It is a local server and only handles certain RESTful URLs. Can you explain a little bit?

The version you show completely removes the security features IPC brings to the table.

I believe what he want to say is IPC is not exposed, your API and files can only be loaded from Electron itself, your approach will allow user to say, open Chrome and go to the address directly

@draeder
Copy link

draeder commented Jun 30, 2022

@curlyz You are correct. I actually ended up using @dirkk0 's version to embed a Gun DB relay server inside of Electron which needs to be exposed to the local network. It actually turned out to be quite useful.. so Thank you @dirkk0

@dirkk0
Copy link

dirkk0 commented Jun 30, 2022

@draeder you are very welcome. Thanks for letting us know that it works for you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment