i have an application written in nodejs and angularjs . In index page bottom of there is an hyperlink text.when i click on that hyper link page is loading but when i refresh same page it give 404 error .
When you refresh the page, you are telling the http server to handle a GET request for some resource that matches the hyperlink address.
Assume this address is path/to/resource.
When the server receives that request, it looks for a static resource or a handler that matches that path. If it does not find one, it returns a 404.
Assuming that the hyperlinked resource is something withing your angular app, you need to server the index.html page again regardless of what is requested. This will allow the angular app to bootstrap, parse the route, and go through its own routing to reload that page.
If you're using Express then this code would do the trick:
var app = require('express');
app.use('*', function (req, res, next) {
res.sendfile('index.html');
return next();
});
Now every request will return index file and Angular will do the rest.
Related
I am trying to setup a login system on a website.
In order to do that, I have to load http only cookies.
In order to load them, I have to send them back to the client via the response object in the createServer function when https starts up.
I have successfully done that via here:
setting up https cookie in nodejs
The problem is twofold.
The https server cookie only loads if I include the port number in the url.
How do I get it to load without including the port number?
When the server kicks in and loads the cookie, the static index.html that was always supposed to load on the client, doesn't load and instead all i get is what was written into the response object on the server. How do I get to load the cookie, and just load that static html file?
I have tried sending in the entire html file as a respnose from the server side. But I'm not sure about that, plus i get MIME type problems in the browser.
I am not sure for the first part but for 2nd one,
you have to properly mention about response data type in response header.
so your should be something like this one:
var app = express(); app.get('/test', function(req, res) { res.sendFile('views/test.html', {root:__dirname}) });
For your first part of the question "How do I get it to load without including the port number?" You can try creating virtual host e.g for localhost:3000 will be something.xyz.
And for your second part you need to serve index.html with render method as follow
server.get('/', function (req, res) {
res.render('index', { greeting: 'Welcome' });
});
Where index is you static file inside view directory.
I've created a small demo, that might get you on the right track:
https://github.com/bergur/simple-server-with-websocket
This example includes:
https web server
websocket server
logic to get the cookies
serving a temp.html file without express
example of javascript class
example of dependency injection in nodejs
I'm not sure if this is a security feature or if I'm missing something obvious. I need to access one of my ExpressJS routes directly via a standard link on the page.
If I type the URL in to my browser location bar, I get the desired result. However, if I put that exact URL in a standard link on one of the pages on the site, the route never gets hit.
EDIT: Even if I pull this out of the router and add directly to app.js I get the same results. I'm simply trying to use Passport's Facebook authentication. The first route looks like this:
router.get('/login/facebook', function(req, res, next) {
passport.authenticate('facebook')(req, res, next);
});
I realize the req function wrapper is not needed, I was using it for debugging so I could see when the route gets called.
If I set a breakpoint there, it works fine if I just type the "/api/login/facebook" URL into my browser, but if I put the exact URL in a link on the page, the route never gets hit.
It turns out this was caused by Angular's routing mechanism intercepting the links. I found the solution here:
How to get Angular UI Router to respect "non-routed" URLs
I am building freeboard using freeboard.io. I am running it on a node server using express. I use
router.get('/', function(req, res, next) {
res.sendFile(path.join(__dirname + '/index.html'));
});
to send the freeboard html file when the base route is hit. However, in order for freeboard to load my saved dashboard I need to append #source=dashboard.json to the url. So the final url would look like
http://localhost:8080/#source=dashboard.json
is there some way I can do this using express? Pretty much when I hit localhost:8080/ I want to append to the url path #source=dashboard.json and respond with the index.html file. Thanks!
The fragment section of the URL is never sent to the server by the browser. See here for more info. Therefore for the server the fragment will always be missing even if the user has entered it on the URL field. In this case redirecting the browser back with the same URL inclusing the fragment may be the wrong thing.
My client side code is a single page app (written in knockout.js) with its own routing system so when google crawler bot will try to access links (that have nothing to do with requesting new page from back end BUT just a part of client side routing) it will ask server (node.js + express.js) to serve page (for example 'mywebsite/about') and of course server will return 404 because it unawares of client routing system. Here is my current server code:
router.get('*', function(req, res, next) {
res.sendFile(path.resolve('../dist/index.html'));
});
My idea is to define the same routing structure as in a client and pass routs for client routing system in search parameter:
router.get('/about', function(req, res, next) {
res.sendFile(path.resolve('../dist/index.html?tab=about'));
});
then in client side I can catch it in javascript and pick correct route.
Here off course I have another problem - as I understand google bot doesn't run javascript.. but here I can use prerender.io middleware I guess.
1) Is it a right way to go with single page apps with generated content and SEO?
2) How to pass search parameter from express.js?
If you have query strings that Googlebot can use to recall consistent content then you can indicate this in Webmaster:
https://support.google.com/webmasters/answer/6080548?rd=1
Here's an example set up of mine:
Google wants to only index pages that have consistent content. If content varies for each user - then you want to set a rel="canonical" tag on each page indicating where the 'start' would be for this dynamically generated content.
The idea would be to adapt the Webmaster to your app rather than the other way around. Trying to 'trick' the bot can have dire consequences in SEO because Google does have human checkers that occasionally rate domains. If they find inconsistency between the search indexed URL and what they see in their browser, you'll earn a flag from a lazy operator. Here is the handbook operators follow.
Use prerender.io as first middleware of your pipe:
app.use(require('prerender-node').set('prerenderToken', 'YOUR_TOKEN'));
app.get('*', (req, res) => res.render('index.html'));
I'm using Express, which loads AngularJS from a static directory. Normally, I will request http://localhost/, in which Express serves me my index.html and all of the correct Angular files, etc. In my Angular app, I have these routes setup, which replace the content in an ng-view:
$routeProvider.when('/', {
templateUrl: '/partials/main.html',
controller: MainCtrl,
});
$routeProvider.when('/project/:projectId', {
templateUrl: '/partials/project.html',
controller: ProjectCtrl,
});
$locationProvider.html5Mode(true);
On my main page, I have a link to <a href="/project/{{project.id}}">, which will successfully load the template and direct me to http://localhost/project/3 or whatever ID I have specified. The problem is when I try to direct my browser to http://localhost/project/3 or refresh the page, the request is going to the Express/Node server, which returns Cannot GET /project/3.
How do I setup my Express routes to accommodate for this? I'm guessing it will require the use of $location in Angular (although I'd prefer to avoid the ugly ?searches and #hashes they use), but I'm clueless about how to go about setting up the Express routes to handle this.
Thanks.
with express 4, you probably want to catch all requests and redirect to angularjs index.html page.
app.use(app.router); doesn't exist anymore and res.sendfile is deprecated, use res.sendFilewith an uppercase F.
app.post('/projects/', projectController.createProject);
app.get('/projects/:id', projectController.getProject);
app.get('*', function (req, res) {
res.sendFile('/public/index.html');
});
put all your API routes before the route for every path app.get('*', function (req, res){...})
I would create a catch-all handler that runs after your regular routes that sends the necessary data.
app = express();
// your normal configuration like `app.use(express.bodyParser());` here
// ...
app.use(app.router);
app.use(function(req, res) {
// Use res.sendfile, as it streams instead of reading the file into memory.
res.sendfile(__dirname + '/public/index.html');
});
app.router is the middleware that runs all of your Express routes (like app.get and app.post); normally, Express puts this at the very end of the middleware chain automatically, but you can also add it to the chain explicitly, like we did here.
Then, if the URL isn't handled by app.router, the last middleware will send the Angular HTML view down to the client. This will happen for any URL that isn't handled by the other middleware, so your Angular app will have to handle invalid routes correctly.
I guess I should have clarified that I wasn't interested in using a template engine, but having Angular pull all of the HTML partials on it's own, Node is functioning completely as a static server here (but it won't be for the JSON API. Brian Ford shows how to do it using Jade here: http://briantford.com/blog/angular-express.html
My app is a single-page app, so I created an Express route for each possible URL pattern, and each of them does the same thing.
fs.readFile(__dirname + '/public/index.html', 'utf8', function(err, content) {
res.send(content);
});
I was assuming I would have to pass some request variables to Angular, but it looks like Angular takes care of it automatically.