Socket.IO Getting 404 Errors on Some URLs, but not others - javascript

I am trying to use Socket.IO in my web application and it has worked great so far. However, I have been trying to fix one specific issue for a long time and have not been able to find anyone else having the same issue. Socket.IO works great on URLs where it is just site.com/example, however, when I stack paths on the domain, I get a 404 in socket.IO. For example, site.com/user/example displays a 404 for socket.IO. In the log, it tries to access socket.IO at site.com/user/socket.io/... when it needs to access it at site.com/socket.io. It seems to only replace the url after the last / so site.com/ex/a would make it try to get socket.io at site.come/ex/socket.io.(I am using ExpressJS, I didn't know if that was relevant.)
I have tried to set the path and resource for socket.io to use in the client script. Also, I included the path when binding the socket.io instance to the http server.
Here is my server side code.
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server, {path: '/socket.io'});
Here is my client side code.
var socket = io.connect('https://example.net', {
path: '/socket.io',
resource: '/socket.io',
transports: ['websocket'],
upgrade: false
})
Thanks so much for all help!
(I am sorry for any incorrect formatting of this question, this is my fist time asking on StackOverflow!)

You likely need a leading slash on the socket.io script tag.
The big clue is when you said your socket.io script loads when the page URL is https://example.net/dashboard, but doesn't load when it's https://example.net/user/fludo. And, the screen shot shows it trying to load the script from https://example.net/user/fludo/socket.io/socket.io.js which is, indeed, the wrong path.
The problem is that your <script> tag is using a page relative link with no leading / on the URL. That means the browser will combine the path of the page URL with the filename in your <script> tag. But, you don't want to use the path of the page. You want to load it from the same place every time. So, to do that, you change from this:
<script src="socket.io/socket.io.js"></script>
to this:
<script src="/socket.io/socket.io.js"></script>

Related

Redirect a specific url that is not found with javascript in header

I moved my website and I have a QR code (which is printed in public and can't be easily replaced) that points to a specific file on my old website that has now been moved. Currently, the URL just points to a "Not found" page on my new website. I try to use javascript in the header to catch the URL and forward it to the right URL as following:
<script type="text/javascript">
if(window.location.href === "https://www.website.com/multimedia/hoerproben/1.mp3")
{
window.location.href = "https://www.webseite.com/app/download/10079133850/1.mp3";
}
</script>
But it doesn't work. Any hints what I am doing wrong?
when you open an url, the browser makes an http request to your server for that particular resource (in your example, an mp3 file).
JavaScript is not involved at all (actually, there are so called "service workers", but they are not what you're looking for, they are meant to do caching, not redirecting). The browser does not know that your JavaScript code exists and would not execute it.
What you should do is route redirecting from server, so when the browser asks from /oldlocation/file.mp3, instead the server answers with /newlocation/file.mp3
This could be in some different way according to your server. If you have no control on how your server works, what you're asking is simply not possibile.
It won't work unless you place that code in the "Not found" page that gets served. If your URL pointed to an HTML file, you could have just placed one to do the redirect. For media files you would have to configure your server to serve an HTML file instead. Don't worry about the extension, it's the Content-Type header that determines the type of the file served. Doing this, however, is not good practice because your server would still be returning a 200 response code.
It's good practice to return 301 Moved Permanently as 101arrowz pointed out in the comments. How that can be accomplished will depend on what server you're using.
Here's how that would have been accomplished with express.js:
app.get('/multimedia/hoerproben/1.mp3', function(req, res) {
res.redirect('/app/download/10079133850/1.mp3');
});

What did I just implement with Node.js?

I'm following this tutorial, I was confused at the point where it says:
"...
Surprisingly the code is very simple:"
// Connect to the socket.io server
var socket = io.connect('http://localhost:8080');
// Wait for data from the server
socket.on('output', function (data) {
...
I'm not sure where to put this code. I tried to add it to browser JS, like this:
<html>
<head>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script> <!-- here -->
// Connect to the socket.io server
var socket = io.connect('http://localhost:8080');
// ...
</script>
</head>
<body>
<h1>SSH</h1>
<div class="terminal"></div>
</body>
</html>
And it worked! Is this correct? I thought it was meant to be a server-side code.
Anyways, now I get a terminal which i can interact with. But I'm not sure what it is doing. I was trying to implement an SSH client, but it looks like I obtained an on-browser terminal, over which I will manually connect to SSH?
Also I believe this would only work on the local machine. But what I want is a -remote- web server that can access to my machine using SSH (although it may not be very safe). Am I in the right direction? How can I implement a web server that acts as a client to the SSH server on my machine?
Thanks,
It has absolutely NOTHING to do with SSH in any way, shape or form.
It's a websocket server/client, which allows you to send messages(not commands) between a browser and a server.
It's most commonly used for chat applications, although there are endless other uses.
However, with this mechanism in place, you could interpret certain messages on the server and make them execute the commands you wish to allow your users to use.
Quick example of how it would work (server side) :
socket.on('ls',(path,cb)=>{
fs.readdir(path, (err, files) => {
cb(files);
});
});
and on the client :
socket.emit('ls','/home',(files)=>{
console.log(files);
};
The client here emits a 'ls' event, with a path (user selected or something); and the server interprets this message, get the list of files for the given path, and returns it to the client. This mechanism could be used to implement a variety of commands. But keep in mind that this is NOT SSH.
Read more on Socket.io
If you are following the tutorial the server side code is server.js. This is a simple express.js webserver with a socket.io extension.
The code in the .html file is send to the browser which acts as client.
That's a socket server. It listens for connections from the browser. That's what you're doing in the HTML.

External javascript in html is sent incorrectly to the server

I'm running a Node.js server along with an Angular frontend. One of the Angular dependencies I'm using requires me to import a javascript file into my html page, by the name of swing.js. However, when I try to do this, it sends the required file as an http request to the server, resulting in requests that look like the following:
http://localhost:3000/home/me/app/node_modules/angular-swing/dist/swing.js
Obviously, this comes up as a 404. As an alternative, I've tried changing
<script src="/home/me/app/node_modules/angular-swing/dist/swing.js"></script>
into
<script src="swing.js"></script>
and then on the server-side, doing:
app.get('swing.js', function(req, res){
res.sendFile('home/me/app/node_modules/angular-swing/dist/swing.js');
});
This works a little more, but then the file doesn't run properly, as I'm assuming it's no longer in the npm environment it needs to be in. I've tried multiple iterations of changing
<script src="/home/me/app/node_modules/angular-swing/dist/swing.js"></script>
into something that uses periods (.) to represent more relative paths, but that doesn't appear to work either. Overall, I'm very stuck, and would appreciate any insight. If it's of any use, I'm also using:
app.use(express.static(__dirname+'/public'));
Making my comments into an answer...
node.js does not serve any files by default so any script files that you need sent from your server to the client upon request need an explicit route to handle them or they need some generic route that knows how to handle all the requested script files.
swing.js in the client is not part of any "NPM environment". It's running the browser at that point, not in any NPM enviornment. It's possible that swing.js itself needs some other scripts or resources that also need routes and that's why it doesn't work after you make an explicit route for it. You can probably examine the specific errors in the console to give you a clue why it isn't working.
You may also want to read this: How to include scripts located inside the node_modules folder?

What happens if node js doesn't find a client html file?

AM trying to implement a push server for my pHP application.
My initial thoughts were as long as i keep the EVENTS called on my client let say message_view.php file . I would not have a problem of emiting node js events.
But i see that most of the tutorial online use something like I dont understood this ?
fs.readFile(__dirname + '/client.html') ...//html files
or
response.sendfile('hello world')
After they have started the server. Then they add event and logic as follow on the client html file that am supposed to do it on my messages_view.php file.
<script src="socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
and socket emiting events like this one :
<script>
// create a new websocket
var socket = io.connect('http://localhost:8000/?profile_id=abcde2');
//..I want to code here to update my divs.
</script>
What do i need exactly to emit this message on my PHP file. Many Thanks!
If you want to serve html with php, and have a node.js socket server, the socket server doesn't need to serve html, so you can omit the majority of the example you're using. Just include the script in your .php that serves the html page and make sure the url to the script properly targets the socket server.

Angular Removed # tags in urls. But not working as expected

I just removed # tag from my url of angular single page app.
I did like.
$locationProvider.html5Mode(true);
And It worked fine.
My problem is when I directly enter any url to the browser it showing a 404 error. And its working fine when I traverse throughout the app through links.
Eg: www.example.com/search
www.example.com/search_result
www.example.com/project_detail?pid=19
All these url's are working fine. But when I directly enter any of the above url's into my browser it showing a 404 error.
Please any thoughts on it.
Thanks in advance.
Well i had a similar problem. The server side implementation included Spring in my case.
Routing on client side ensures that all the url changes are resolved on the client side. However, When you directly enter any such url in the browser, the browser actually goes to the server for retrieving a web page corresponding to the url.
Now in your case, since these are VIRTUAL urls, that are meaningful on the client side, the server throws 404.
You can capture page not found exception at your server side
implementation, and redirect to the default page [route] in your app.
In Spring, we do have handlers for page not found exceptions, so i
guess they'll be available for your server side implementation too.
When using the History API you are saying:
"Here is a new URL. The other JavaScript I have just run has transformed the page into the page you would have got by visiting that URL."
This requires that you write server side code that will build the page in that state for the other URLs. This isn't a trivial thing to do and will usually require a significant amount of work.
However, in exchange for that work you get robustness and performance. When one of those URLs is visited it will:
work even if the JS fails for any reason (such as a dropped network connection or a client (such as a search engine) that doesn't support JS)
load faster than loading the homepage and then transforming it with JS
You need to use rewrite rules. Angular is an single page app, so all your request should go to the same file(index.html). You could do this by creating an .htaccess.
Assuming your main page is index.html.
Something like this (not tested):
RewriteRule ^(.)*$ / [L,QSA]
L flag means that if the rule matches, don't execute the next RewriteRule.
QSA means that the URL query parameters are also passed with the rewrited url.
More info about htaccess: http://httpd.apache.org/docs/2.2/howto/htaccess.html

Categories

Resources