I have configured my ui-router like this:
app.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', {
url: "/home",
templateUrl : 'home/home.html',
controllerUrl: 'home/controller.js'
})
.state('blog', {
url: "/blog",
templateUrl : 'blogger/blog.html',
controllerUrl: 'bloger/controller.js'
})
$locationProvider.html5Mode({
enabled: true,
requireBase: true
});
});
Server code :
var express = require('express');
var serveStatic = require('serve-static');
var server_port = 9000;
var server_ip_address = '127.0.0.1'
var app = express();
app.use(express.static('app'));
app.use(serveStatic('app', {'index': ['index.html', 'index.htm']}));
dirName = 'app';
options = {
root: dirName,
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
};
app.get('*', function(req, res) {
return res.sendFile('index.html', options);
});
app.listen(server_port, server_ip_address, function () {
console.log( "Listening on " + server_ip_address + ", server_port " + server_port)
});
But whenever I hit Ctrl/Command + R (or refresh), it says that it cannot find the path? How can I get around this problem?
Folder structure : Views : ./app/home/, app/blog/ Basefile:
./app/index.html Angular UI-routing from : ./app/base.js
The problem would be in the server settings. Angular is Front Controller application. You need every request redirect to index.html/index.php on your server. Htaccess settings in apache for example. Further information can be found here: htaccess redirect for Angular routes
The Problem is from your server side you should handle all routes in your server.js file.
For Example here is the snippet
router = settings.express.Router()
dirName = settings.path.resolve(__dirname, '..', '..');
options = {
root: dirName + '/website/views',
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
};
router.get('*', function(req, res) {
return res.sendFile('index.html', options);
});
You can Use the below code in your app.js, & then it work :
UPDATED :
/** Below code set the html as your default engine*/
var fs = require('fs');
app.engine('html',function(path,opt,fn){ //manishp
fs.readFile(path,'utf-8',function(err,str){
if(err) return str;
return fn(null,str);
});
});
app.get('*',function(req,res){
res.render('<your_layout_file_or_basefile>');
});
This is mainly because your AngularJS routes aren't actual html pages. An example would be if you have a route in your angular app to /login. This url works fine if you link to it from inside your app but if a user tries to go directly to that page the server will return a 404.
This is because AngularJS HTML5 mode uses the History API to push a new url to your browser. Yes, this require some extra work on the server side to have those url return the correct content.
Related
I have built a mean-stack application. I use http to communicate data between front-end and back-end. For example,
In front-end, I have
app.factory('ops', ['$http', function ($http) {
var o = {};
o.get = function (id) {
return $http.get('/ops/' + id)
.then(function (res) {
return res.data
})
};
return o;
}]);
In the back-end, in routes/index.js, I have
var express = require('express');
var router = express.Router();
... ...
router.get('/ops/:op', function (req, res, next) {
console.log("/ops/:op");
res.json(req.op);
})
module.exports = router;
And it is the job of ui-router to load a page like https://localhost:3000/ops/59202d6a38b09685ff6b0581:
.state('ops', {
url: '/ops/{id}',
...
However, since I turned html5Mode to true, it seems that router.get('/ops/:op', function (req, res, next) { console.log("/ops/:op"); res.json(req.op); }) can directly load the page https://localhost:3000/ops/59202d6a38b09685ff6b0581. If I comment .state('ops' ... and load the page, I see /ops/:op is displayed in the server console, and the content of the json data is shown in the browser. At the same time, in the browser console, I see
Resource interpreted as Document but transferred with MIME type application/json: "https://localhost:3000/ops/59202d6a38b09685ff6b0581"
Could anyone tell me if we should let router.get('/ops/:op' ... intervenue the loading of a page in this way? If not, how could we disable it?
PS: routers/index.js is referenced in app.js as follows:
var index = require('./routes/index');
app.use('/', index);
So I'm uising nightmare to generate scenarios of users using a page to get the HTTP-Requests of the page proxy-ed
To do so I'm using http-proxy and setting it like this :
var http = require('http'),
httpProxy = require('http-proxy');
httpProxy.createProxyServer({target:'http://localhost:9000', auth: 'test:test'}).listen(8000);
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
and then I use nightmare like this :
var nightmare = Nightmare({show: true,
switches : {
'proxy-server': 'localhost:9000;',
'ignore-certificate-errors': true,
}})
nightmare.authentication('test', 'test')
.goto('http://localhost:4200/login')
.type('#name', 'test'+user)
.type('#pwd', 'test'+user)
.click('#log')
.wait('body')
but when I launch it, nightmare goes on the proxy (so localhost:9000) and ignores the goto(localhost:4200), can someone help me?
I am trying to get a https loopback server up and running protected by OAuth. I am using the loopback gateway sample project as a reference. But for some reason I can't get the OAuth piece to work. What I mean is, even after adding in the OAuth bits and pieces, the APIs don't seem to be protected. I get a response back even if there is no token in my request. This is what my server.js looks like
var loopback = require('loopback');
var boot = require('loopback-boot');
var https = require('https');
var path = require('path');
var httpsRedirect = require('./middleware/https-redirect');
var site = require('./site');
var sslConfig = require('./ssl-config');
var options = {
key: sslConfig.privateKey,
cert: sslConfig.certificate
};
var app = module.exports = loopback();
// Set up the /favicon.ico
app.middleware('initial', loopback.favicon());
// request pre-processing middleware
app.middleware('initial', loopback.compress());
app.middleware('session', loopback.session({ saveUninitialized: true,
resave: true, secret: 'keyboard cat' }));
// -- Add your pre-processing middleware here --
// boot scripts mount components like REST API
boot(app, __dirname);
// Redirect http requests to https
var httpsPort = app.get('https-port');
app.middleware('routes', httpsRedirect({httpsPort: httpsPort}));
var oauth2 = require('loopback-component-oauth2')(
app, {
// Data source for oAuth2 metadata persistence
dataSource: app.dataSources.pg,
loginPage: '/login', // The login page url
loginPath: '/login' // The login processing url
});
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// Set up login/logout forms
app.get('/login', site.loginForm);
app.get('/logout', site.logout);
app.get('/account', site.account);
app.get('/callback', site.callbackPage);
var auth = oauth2.authenticate({session: false, scope: 'demo'});
app.use(['/protected', '/api', '/me', '/_internal'], auth);
app.get('/me', function(req, res) {
// req.authInfo is set using the `info` argument supplied by
// `BearerStrategy`. It is typically used to indicate scope of the token,
// and used in access control checks. For illustrative purposes, this
// example simply returns the scope in the response.
res.json({ 'user_id': req.user.id, name: req.user.username,
accessToken: req.authInfo.accessToken });
});
signupTestUserAndApp();
//var rateLimiting = require('./middleware/rate-limiting');
//app.middleware('routes:after', rateLimiting({limit: 100, interval: 60000}));
//var proxy = require('./middleware/proxy');
//var proxyOptions = require('./middleware/proxy/config.json');
//app.middleware('routes:after', proxy(proxyOptions));
app.middleware('files',
loopback.static(path.join(__dirname, '../client/public')));
app.middleware('files', '/admin',
loopback.static(path.join(__dirname, '../client/admin')));
// Requests that get this far won't be handled
// by any middleware. Convert them into a 404 error
// that will be handled later down the chain.
app.middleware('final', loopback.urlNotFound());
// The ultimate error handler.
app.middleware('final', loopback.errorHandler());
app.start = function(httpOnly) {
if(httpOnly === undefined) {
httpOnly = process.env.HTTP;
}
server = https.createServer(options, app);
server.listen(app.get('port'), function() {
var baseUrl = (httpOnly? 'http://' : 'https://') + app.get('host') + ':' + app.get('port');
app.emit('started', baseUrl);
console.log('LoopBack server listening # %s%s', baseUrl, '/');
});
return server;};
// start the server if `$ node server.js`
if (require.main === module) {
app.start();
}
function signupTestUserAndApp() {
// Create a dummy user and client app
app.models.User.create({username: 'bob',
password: 'secret',
email: 'foo#bar.com'}, function(err, user) {
if (!err) {
console.log('User registered: username=%s password=%s',
user.username, 'secret');
}
// Hack to set the app id to a fixed value so that we don't have to change
// the client settings
app.models.Application.beforeSave = function(next) {
this.id = 123;
this.restApiKey = 'secret';
next();
};
app.models.Application.register(
user.username,
'demo-app',
{
publicKey: sslConfig.certificate
},
function(err, demo) {
if (err) {
console.error(err);
} else {
console.log('Client application registered: id=%s key=%s',
demo.id, demo.restApiKey);
}
}
);
});
}
I don't get any errors when the server starts up. Thoughts?
Got it figured. More information here https://github.com/strongloop/loopback-gateway/issues/17, but basically I had my rest-api middleware not configured right.
I am now using angular-file-upload packages to upload files. After I press item.upload(), it claims to be successfully uploaded the file, but I see the req.body is empty. Please Help!
Here is the angular code to handle it:
var uploader = $scope.uploader = $fileUploader.create({
scope: $scope, // to automatically update the html. Default: $rootScope
url: '/api/teams/upload',
formData: [
{ key: 'value' }
],
filters: [
function (item) { // first user filter
$scope.previewImage(item);
return true;
}
]
});
And here is the way to trigger the upload:
uploader.bind('afteraddingfile', function (event, item) {
// console.info(item.file);
console.info('After adding a file', item);
// console.log('item.upload();');
item.upload();
});
And finally here is the express js code:
exports.upload = function(req, res) {
// console.log('req.headers');
// console.log(req.headers);
console.log('req.body');
console.log(req.body);
What wrong's with it?
First make sure your POST is encoded as enctype="multipart/form-data"....
In Express 4 you need to set the body parser in your server:
var bodyParser = require('dy-parser');
//...
var app = express();
//...
app.use(bodyParser()); // pull information from html in POST
var busboy = require('connect-busboy');
app.use(busboy());
In earlier version of Express you only needed to add the body parser from the framework itself and files will be store on the configured location:
app.use(express.bodyParser({limit: '10mb', uploadDir: __dirname + '/public/uploads' })); // pull information from html in POST
Since version 4 removed support for connect now you need to add your custom support for multipart/form data to parser multi/part POSTs, so you will have to to do something like:
var fs = require('fs');
var busboy = require('connect-busboy');
//...
app.use(busboy());
//...
app.post('/api/teams/upload', function(req, res) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
console.log("Uploading: " + filename);
fstream = fs.createWriteStream(__dirname + '/files/' + filename);
file.pipe(fstream);
fstream.on('close', function () {
res.redirect('back');
});
});
});
On the client side you need to call the $upload.upload To start the upload
I'm trying to write restful application using node.js restify. Here is my application's code :
var restify = require('restify');
var server = restify.createServer();
server.get(/.*/, restify.serveStatic({
directory: 'content',
default: 'index.html'
}));
server.listen(3000, function() {
console.log('%s listening at %s', server.name, server.url);
});
So, I can access index.html only by http://localhost:3000/index.html.
I also expect to see my index.html page on the root url, http://localhost:3000/ but now i'm receiving there
{"code":"ResourceNotFound","message":"/"}
Give this a try:
server.get(/\//, restify.serveStatic({
directory: './content',
default: 'index.html'
}));