Hi,
I have been working on a project using json-server on localhost. It worked well until I wanted it to serve JSON responses from an actual server. Now, I have hosted my front-end code in Apache (under HTTPS) and ran json-server as a background process using nohup in my server. After this, the front-end code is unable to access any response from json-server.
I see multiple issues here -
I could not find a solution for this. Any idea how I can run json-server under HTTPS on an actual server? Any help would be much appreciated.
PS. json-server is able to serve responses when the front-end is served from HTTP. However, I am using service workers in my project which need HTTPS to work.
Hi @kranthilakum,
I guess there's many way to solve it, you can:
--host and --port if you need to make it run on some other port/host--static to tell JSON Server to serve your static files, so there shouldn't be an issue with mixed content anymore https://github.com/typicode/json-server#static-file-serverYou can also probably configure Apache to proxy requests to JSON Server or use some other tools to do this.
Personally, I would suggest using JSON Server's static file server and hotel if you need https.
@typicode Thank you for the response!
A practical example of how to use hotel and and json-server with https is completely lacking on the internet it seems. Can anyone offer some steps on how to get it working?
@Gribbs - See if this helps. I had the same issue and the following steps work for me. I am providing steps for windows, and steps on unix based OS should be the same, except variable representation ($ instead of % etc.).
Hope this helps.
@typicode - Could these steps be added as a complete guide for setting up json-server and hotel to provide https. It wasn't clear at first and this could save a lot of time. Thanks!
I do use a custom server.js
Create your cert
openssl req -nodes -new -x509 -keyout server.key -out server.cert
// https-json-server.js
import jsonServer from 'json-server';
import https from 'https';
import path from 'path';
import fs from 'fs';
const server = jsonServer.create();
const keyFile = path.join(__dirname, 'server.key');
const certFile = path.join(__dirname, 'server.cert');
https
.createServer(
{
key: fs.readFileSync(keyFile),
cert: fs.readFileSync(certFile),
},
server
)
.listen(3000, () => {
console.log(
'Go to https://localhost:3000/'
);
});
And then start node https-json-server.js
Hi @luishdez, I don't have much js knowledge. I'm actually trying to migrate the https option to a docker container, but I can't make it work even with this js template you show.
Heres the file I created:
// https-json-server.js
import jsonServer from 'json-server';
import https from 'https';
import path from 'path';
import fs from 'fs';
const server = jsonServer.create();
const keyFile = path.join(/usr/src/app, 'server.key');
const certFile = path.join(/usr/src/app, 'server.cert');
https
.createServer(
{
key: fs.readFileSync(keyFile),
cert: fs.readFileSync(certFile),
},
server
)
.listen(3000, () => {
console.log(
'Go to https://localhost:3000/'
);
});
I ran
npm install -g json-server
then
node https-json-server.js
it gives me this error:
MAC:node_modules galiad$ cd json-server/
MAC:json-server galiad$ node https-json-server.js
(node:57757) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
/usr/local/lib/node_modules/json-server/https-json-server.js:2
import jsonServer from 'json-server';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at wrapSafe (internal/modules/cjs/loader.js:1060:16)
at Module._compile (internal/modules/cjs/loader.js:1108:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1164:10)
at Module.load (internal/modules/cjs/loader.js:993:32)
at Function.Module._load (internal/modules/cjs/loader.js:892:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
Do you have any clues or a more detailed step how to run this?
The '__dirname' is the directory to my docker folder and I copied the certificates before running the commands, but it doesn't even import the jsonServer from json-server.
I'm running node version 13.6.0
Thank you and sorry for my lack ok knowledge on this area.
@adrianogalindo Check npm install was executed in the Dockerfile, check Node version and see if supports ES6 (import) if not use Babel to compile first.
@adrianogalindo To fix the module issue, use require instead of import.
Here is the code I ended up using that works for me:
// https-json-server.js
// Run with: node https-json-server.js
// Generate SSL keys: openssl req -nodes -new -x509 -keyout server.key -out server.cert
const jsonServer = require("json-server");
const https = require("https");
const path = require("path");
const fs = require("fs");
const pause = require('connect-pause'); // Install: npm install connect-pause
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();
server.use(middlewares);
// To handle POST, PUT and PATCH you need to use a body-parser
// You can use the one used by JSON Server
server.use(jsonServer.bodyParser)
server.use((req, res, next) => {
if (req.method === 'POST') {
req.body.createdAt = Date.now()
}
// Continue to JSON Server router
next()
})
server.use(pause(2000));
server.use(router);
// If using custom routes
//var routes = JSON.parse(fs.readFileSync('routes.json'));
//server.use(jsonServer.rewriter(routes));
const keyFile = path.join(__dirname, 'server.key');
const certFile = path.join(__dirname, 'server.cert');
https
.createServer(
{
key: fs.readFileSync(keyFile),
cert: fs.readFileSync(certFile),
},
server
)
.listen(3001, () => {
console.log(
'Go to https://localhost:3001/'
);
});
In Chrome, you can use url chrome://flags/#allow-insecure-localhost to allow insecure localhost.
@adrianogalindo To fix the module issue, use require instead of import.
Here is the code I ended up using that works for me:
// https-json-server.js // Run with: node https-json-server.js // Generate SSL keys: openssl req -nodes -new -x509 -keyout server.key -out server.cert const jsonServer = require("json-server"); const https = require("https"); const path = require("path"); const fs = require("fs"); const pause = require('connect-pause'); // Install: npm install connect-pause const server = jsonServer.create(); const router = jsonServer.router('db.json'); const middlewares = jsonServer.defaults(); server.use(middlewares); // To handle POST, PUT and PATCH you need to use a body-parser // You can use the one used by JSON Server server.use(jsonServer.bodyParser) server.use((req, res, next) => { if (req.method === 'POST') { req.body.createdAt = Date.now() } // Continue to JSON Server router next() }) server.use(pause(2000)); server.use(router); // If using custom routes //var routes = JSON.parse(fs.readFileSync('routes.json')); //server.use(jsonServer.rewriter(routes)); const keyFile = path.join(__dirname, 'server.key'); const certFile = path.join(__dirname, 'server.cert'); https .createServer( { key: fs.readFileSync(keyFile), cert: fs.readFileSync(certFile), }, server ) .listen(3001, () => { console.log( 'Go to https://localhost:3001/' ); });
How to expose it to with --host option? I mean external IP?
Most helpful comment
A practical example of how to use hotel and and json-server with https is completely lacking on the internet it seems. Can anyone offer some steps on how to get it working?