nodejs config on subdirectory - javascript

I have a sub-domain and I publish my server.js on this directory. everything work fine. but I want to running my server.js inside a directory(because I want to run my react.js project on sub directory). for example:
web.example.com/sr
web is my subdomain and sr is my directory.
but my routes not worked at all:
web.example.com/sr/user/1
I got this error message:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /sr/user/1</pre>
</body>
</html>
Should I make any changes or is there any config to do this?

You can't do deployment-level configs to serve your react app to the subdir /sr. Every call to your.domain.com/sr/* will end up in your server and pass /sr/* to it (and not simply /*.
You'll have to code your server to serve your React app. If you bundle your react app to index.html and bundle.js, you'll have to write something like this (if you're using express, which you probably do):
app.get(/\/sr\/\.js/, (req, res) => res.sendFile(`${__dirname}/bundle.js`));
app.get(/\/sr\/*/, (req, res) => res.sendFile(`${__dirname}/index.html`));
If you're using react-router, you'll have to set it up too so as to take into account the leading /sr in your URL.

Related

Socket.io - socket.io.js not available

I need to get a socket.io server running using python.
I followed this example:
https://tutorialedge.net/python/python-socket-io-tutorial/
With the final files looking as follows:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<button onClick="sendMsg()">Hit Me</button>
<!--WORKS:-->
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>-->
<!-- DOESNT WORK:-->
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
<script>
const socket = io("http://localhost:8080");
function sendMsg() {
socket.emit("message", "HELLO WORLD");
}
socket.on("message", function(data) {
console.log(data);
});
</script>
</body>
</html>
server.py
from aiohttp import web
import socketio
sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)
async def index(request):
with open('index.html') as f:
return web.Response(text=f.read(), content_type='text/html')
#sio.on('message')
async def print_message(sid, message):
print("Socket ID-: " , sid)
print(message)
await sio.emit('message', message[::-1])
app.router.add_get('/', index)
if __name__ == '__main__':
web.run_app(app)
So much this is only copy paste and thus works fine, but I dont want to use the script from some online source. So I tried to modify the src of the script by commenting out the running version and replacing it by a version using a local socket.io.js.
As I did not find the script on my machine I found the following questions, that both did not help me solve my issue:
node-js-socket-io-socket-io-js-not-found
socket-io-not-being-served-by-node-js-server
No matter what I do I get the following error in my browser:
GET http://localhost:8080/node_modules/socket.io/socket.io.js net::ERR_ABORTED 404 (Not Found)
(index):18 Uncaught ReferenceError: io is not defined
at (index):18
(anonymous) # (index):18
From what I understood from the 2 linked threads, my server should provide the socket.io/socket.io.js when listen is called on the server.
Unfortunately this is not happening in my case.
I had socket.io installed via pip, I also tried npm install socket.io --save as suggested, this gives me a new folder 'node_modules', but modifying the src for my script to:
<script src="http://localhost:8080/node_modules/socket.io/socket.io.js"></script>
doesnt help either.
For some reason using the fie from cdnjs works just fine (see my index.html).
I would be very glad if someone could help me out with this.
Cheers
Chris
I've never worked with AIOHTTP (always worked with flask-socketio) so I did some research using the documentation. It turns out that like a lot of http server, AIOHTTP doesn't serve static files out of the box.
You will thus need to take care of it using the add_static method (doc here).
(Note that if you want to deploy this app for production it would be better practice to use an HTTP server like Apache or Nginx).
Just add this line under your routes declarations.
app.router.add_static('/static/', path='static/')
Now you need to create a static folder in the root of your project and put your socket.io.js file inside of it.
Make sure that the socket.io.js in the version 2.2 (same as the CDN version). You can get this file by downloading it directly from the CDN URL you were using or using npm -i -s socket.io-client#2.2. You can then find the socket.io.js file in node_modules/socket.io-client/dist.
You now just need to use <script src="/static/socket.io.js"></script> in your HTML to import socket.io.

App works fine on 127.0.0.1, but not when accessed from another device

I managed to publish my app with nodejs and I am able to access it from devices in my network (mind you its going to be a local app only). It is an app that is used to control other hardware connected to my network.
The problem I am having right now is that, the app is working fine when I open it from 127.0.0.1:8081 from my local PC on which it is hosted, but if I attempt to open it from another device (or even from the hosting PC itself) by using the IP of the hosting PC 192.168.z.z:8081, the javascript files dont work and here is what I mean.
I have a config.js file which holds configuration data that my app needs to work, like IP of the device that I am controlling.
var config = {
URL: '192.168.0.2',
}
Then I have a Model.js file that has SetData and GetData which are both dependent on config.URL to execute their AJAX requests, however config.URL stays null, its hardcoded and still a null!
When I run the app and do config.URL in the console, I get null, even if I manually set it in the console config.URL = '192.168.0.2', and then try to invoke Model.SetData..... or Model.GetData... they still dont see it, they still are attempting to send a request to http://null/......
Here is my node code:
const express = require("express");
const app = express();
const port = 8081
app.use(express.static('public'))
app.use('/css', express.static(__dirname + '/public/css'));
app.use('/js', express.static(__dirname + '/public/js'));
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));
I have tried with and without the app.use(/css and /js lines of code, no change
Here is how my JS is added to my html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Robot Stuff</title>
<script type="text/javascript" src="./js/jquery-3.5.0.js"></script>
<script type="text/javascript" src="./assets/scripts/main.js"></script>
<script type="text/javascript" src="./js/easy-numpad.js"></script>
<script type="text/javascript" src="./js/jquery-modal.js"></script>
<script type="text/javascript" src="./js/Model.js"></script>
<script type="text/javascript" src="./js/UI.js"></script>
<script type="text/javascript" src="./js/config.js"></script>
<link href="./css/main.css" rel="stylesheet" type="text/css" >
<link href="./css/easy-numpad.css" rel="stylesheet" type="text/css" >
Again, if I open that app from http://127.0.0.1:8081, or if I directly go and double-click on my index.html file, it all works just fine, but when I use the actual IP of the PC to access it remotely, then it breaks.
I dont want to overcomplicate it more than necessary, I am simply trying to use node explicitly to make the app available on my network, nothing more.
You need to allow cross origin policy in your server script.
That will enable you to accept request headers from your other devices also.
npm i cors --save
or alternatively you can follow this guide
Enable CORS in nodejs
Check with netstat -nlp if your server is working on 0.0.0.0 or 127.0.0.1. This could possibly be one of the issue for non-accessibility outside localhost.

Using s3, node js

i'm trying to make a http request using 'request' for nodeJS. But it doesn't work.
It keeps writing 'require is not defined'. I have uploaded my index.html file to my s3 bucket, as well as my node_modules folder and my package.json file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.20/browser.min.js"></script>
<script data-main="js.config" src="js/r.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
const request = require('request');
</script>
This is how the index.html file looks like. It's not the whole file. But it's only the 'require' part is making trouble..
Let me know if you need any more info.
Hope someone can help.
You cannot use the request package on a client side script in that way, pointed out by many of the comments posted. That being said, if you want to have an App with a Node JS Backend for the serverside, you probably shouldn't be using AWS S3 anyways. There are many options for you if you plan to make a Backend App with Node JS:
AWS EC2 with Node JS
AWS Lambda
AWS Elastic Beanstalk
Some of these options, notably the EC2 and Lambda, have free tier options. Hopefully this helps you.

Setting up static assets paths, routing endpoints with koa and various middleares

Question:
How can I set up my static files so that both directories are visible to my index.html.
How can I send my index.html when you hit the default route using koa-router vs. just a .json file when I make an AJAX Get request?
Requirements:
I need static directories to be visible in my apps src/index.html
node_modules needs to be open for js libs.
src/assets needs to be open for images.
I need a router for 2 purposes :
1) serving up the initial index.html
2) CRUD endpoints to my DB.
Notes: I'm totally willing to add/subtract any middleware. But I would rather not change how I organize my directories.
Directory Structure:
Middleware:
koa-static // cant serve node_modules + src directory.
koa-send // can send static files but then breaks koa-static
koa-router // cannot
app.js
var serve = require('koa-static');
var send = require('koa-send');
var router = require('koa-router')();
var koa = require('koa');
var app = koa();
// need this for client side packages.
app.use(serve('./node_modules/'));
// need this for client side images, video, audio etc.
app.use(serve('./src/assets/'));
// Will serve up the inital html until html5 routing takes over.
router.get('/', function *(next) {
// send up src/index.html
});
// will serve json open a socket
router.get('/people', function *(next) {
// send the people.json file
});
app.use(router.routes()).use(router.allowedMethods());
// errors
app.on('error', function(err, ctx){
log.error('server error', err, ctx);
});
app.listen(3000);
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Morningharwood</title>
</head>
<body>
<h1>suchwow</h1>
<img src="./assets/image1.png" alt="butts"> <!-- will 404 with routing -->
<script src="./node_modules/gun/gun.js"></script> <!-- will always 404 -->
<script>
var gun = Gun(options);
console.log(gun);
</script>
</body>
</html>
Well. it happens that I'm developing a similar kind of app
There's no problem on using koa-static to serve you static content and koa-router for you api endpoint. I never used koa-send directly. but I think you doesn't need too, given your set up
The only thing that matters is the order when attaching middleware to koa app. Try to attach koa-static first for your assets ( and maybe even index.html) and later use the koa-router for your api. Requests trying to get some static file never reach the router. and this way the router only responsibility will be serving your api
If that's not posible ( for example, because you have a bunch of non-static html files to server, consider taht you can have more than one router per app, even nesting one inside the other
( If the answer is not enough, give some time to cook a simple example. I'll post it as soon as possible)
EDIT: added a quick and dirty example here. Probably it doesn't work out of the box, but it's enough to get the idea

Enabling html5 mode with AngularJS and a external NodeJS server

So I've read almost every SO answer/question to this topic, but still I have many questions in my head.
First, the problem:
I have an AngularJS app with html5 enabled, so I can get rid of the '#' sign.
$locationProvider.html5Mode({ enabled: true, requireBase: true });
$locationProvider.hashPrefix('!');
This is the important part in my index.html:
<!DOCTYPE html>
<html ng-app="application" ng-controller="ApplicationController as app">
<head>
<meta name="fragment" content="!">
<title>LivingRoomArt</title>
<meta charset="UTF-8">
<base href="/index.html" />
I am communicating with a NodeJS server which is using express:
router.route('/events')
.post(authController.isAuthenticated, eventController.postEvent)
.get(eventController.getEvents);
// Register all our routes with /api
app.use('/api', router);
// Start the server
app.listen(process.env.PORT || 5000);
So, the usual problem:
After reloading, I am getting an 404 from the server. I get the concept of this here, the suggested solution everywhere:
// This route deals enables HTML5Mode by forwarding missing files to the index.html
app.all('/*', function(req, res) {
res.sendfile('index.html');
});
});
The thing is, I don't have an index.html file on my server, neither do
I want to duplicate it on my server.
So how do I tell Node to handle requests properly without storing html-files on my server?
I am hosting the Node app on Heroku, if this helps.
When you say you don't serve static files, you're saying that the node.js API isn't right?
I guess you end up with two distinct urls, let's call them http://api.com and http://client.com.
I don't understand why your API should handle the 404. Do you load http://api.com in your browser and expecting your index.html? If it's really your use-case, I would advice a simple routing to declare in your API like:
app.all('/*', function (req, res) {
res.redirect('http://client.com');
});
Which will redirect all requests not catched by your previous routes declaration to your client website.
Then, there is two options:
If the server that serves your static files is another Node.Js server using express, you could perfectly do the sendfile, since you now have access to the index.html
If you're using Nginx, (which I strongly recommend if you don't) for the statics, you could do a configuration like this to redirect all failed requests (missing files / routes) to the index.html
server {
listen 80;
root /app/www;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}

Categories

Resources