I have an issue where i am not able to serve json files from my sub-folders. Below is the code:
var browserSync = require('browser-sync').create();
// Static server
gulp.task('connect', function() {
browserSync.init({
server: {
baseDir: "app/"
}
});
});
All my static and angularjs files reside inside app folder. When i navigate to http://localhost:3000, the page loads but the corresponding json file inside app/data/myfile.json does not load.
I get the below error in my console:
POST http://localhost:3000/data/json/myfile.json 404 (Not Found)
The strange thing is when i try to load the path in my browser, the json file loads.
At first I used this way https://www.browsersync.io/docs/options/#option-serveStatic FAIL.
But
const ASSET_EXTENSION_REGEX = new RegExp(`\\b(?!\\?)\\.(${config.assetExtensions.join('|')})\\b(?!\\.)`, 'i');
const DEFAULT_FILE = 'index.html';
...
server: {
baseDir: './build',
middleware: function(req, res, next) {
let fileHref = url.parse(req.url).href;
if ( !ASSET_EXTENSION_REGEX.test(fileHref) ) {
req.url = '/' + DEFAULT_FILE;
}
return next();
}
}
...
config = {assetExtensions: [
'js',
'css',
'png',
'jpe?g',
'gif',
'svg',
'eot',
'otf',
'ttc',
'ttf',
'json',
'woff2?' ]}
SUCCESS
Related
I have my server.js file working. at localhost:8080 it will serve the file i give it from the the corresponding url name like so http://localhost:8080/about.html, as long as the file exists in public/pages. I'm wondering if I can somehow set a wildcard to leave of extensions for all html files in the url so that I don't have to individually specify each file as an alias in the routes like - ['about','about.html'].
Here is my working code -
'use strict';
const Path = require('path');
const Hapi = require('hapi');
const server = new Hapi.Server();
server.connection({
port: Number(process.argv[2] || 8080),
host: 'localhost'
});
server.register(require('inert'), (err) => {
if (err) {
throw err;
}
server.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: 'public/pages',
listing: true
}
},
config: {
state: {
parse: false, // parse and store in request.state
failAction: 'ignore' // may also be 'ignore' or 'log'
}
}
});
server.start((err) => {
if (err) {
throw err;
}
console.log('Server running at:', server.info.uri);
});
});
Any help is greatly appreciated, thank you.
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.
In an Angular2 CLI project, i finnaly implemented this upload button from Vaadin. The button UI works, but i don't know how to actually make it upload a file anywhere.
I keep finding solutions about express server that listens for file uploads, multer or node server, and i really have no idea how to write such a server, where to put it, how to start it, how to access it, etc.. I figured that something as trivial as file upload should be easier to achieve, but it seems is not.
What is a simple solution to implement along side Angular2 in order make the button actually upload files somewhere so i can download them later?
Found the solution in ng2-uploader repo and adapted to work with Vaadin Upload.
component.html
<div *ngIf="newName.valid">
<vaadin-upload
target="http://localhost:10050/upload"
</vaadin-upload>
</div>
server.js
'use strict';
const Hapi = require('hapi');
const Inert = require('inert');
const Md5 = require('md5');
const Multiparty = require('multiparty');
const fs = require('fs');
const path = require('path');
const server = new Hapi.Server();
server.connection({ port: 10050, routes: { cors: true } });
server.register(Inert, (err) => {});
const upload = {
payload: {
maxBytes: 209715200,
output: 'stream',
parse: false
},
handler: (request, reply) => {
const form = new Multiparty.Form();
form.parse(request.payload, (err, fields, files) => {
if (err) {
return reply({status: false, msg: err});
}
let responseData = [];
files.file.forEach((file) => {
let fileData = fs.readFileSync(file.path);
const originalName = file.originalFilename;
const generatedName = Md5(new Date().toString() +
originalName) + path.extname(originalName);
const filePath = path.resolve(__dirname, 'uploads',
originalName);
fs.writeFileSync(filePath, fileData);
const data = {
originalName: originalName,
generatedName: generatedName
};
responseData.push(data);
});
reply({status: true, data: responseData});
});
}
};
const uploads = {
handler: {
directory: {
path: path.resolve(__dirname, 'uploads')
}
}
};
server.route([
{ method: 'POST', path: '/upload', config: upload },
{ method: 'GET', path: '/uploads/{path*}', config: uploads }
]);
server.start(() => {
console.log('Upload server running at', server.info.uri);
});
And a bonus for those who need server.js running at startup this is an awesome solution tested and working.
Here is my code:
var logDirectory = __dirname + '/log';
//ensure log directory exists
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);
//create a rotating write stream
var accessLogStream = FileStreamRotator.getStream({
filename: logDirectory + '/access-%DATE%.log',
frequency: 'daily',
verbose: false
})
// setup the logger
//app.use(morgan('combined', {stream: accessLogStream}))
app.use(morgan('combined', {stream: logger.stream}))
/*********************************************************************/
//This is 404 for API requests - UI/View 404s should be
//handled in Angular
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.set('port', 5050);
var server = app.listen(app.get('port'), function () {
//debug('Express server listening on port ' + server.address().port);
console.log('Express server listening on port ' + server.address().port);
});
All the necessary dependencies are being reference and the code references a logger.js file which includes the following code:
var winston = require('winston');
winston.emitErrs = true;
var logger = new winston.Logger({
transports: [
new winston.transports.File({
level: 'info',
filename: './logs/all-logs.log',
handleExceptions: true,
json: true,
maxsize: 5242880, //5MB
maxFiles: 5,
colorize: false
}),
new winston.transports.Console({
level: 'debug',
handleExceptions: true,
json: false,
colorize: true
})
],
exitOnError: false
});
module.exports = logger;
module.exports.stream = {
write: function(message, encoding){
logger.info(message);
}
};
Files are being generated and the file names are timestamped.
Why do my log files have nothing in them?
in place of
app.use(morgan('combined', {stream: logger.stream}))
try using
app.use(morgan('default', { 'stream': logger.stream}));
This should just write the resource and requested and the Browser Info along with a timstamp to your all-logs.log file.
The winston.log won't use your transports
logger.info('test'); will log test to both the console and the file since those are your defined transports.
Is your 'logger' located in a separate .js file or the same as your express server?
Here is my full logger.js file that I use in my express implementations:
https://gist.github.com/pbaio/ac934a06b91b99be6526
I would put that in a separate file in your parent directory such that you would reference it in your server file as such:
var logger= require('..logger.js');
then I would incorporate it as you do now in your middle:
app.use(morgan('combined', {stream: logger.stream}));
I would also delete your logs directory and have the app stop creating the directory all together, then I would recreate the log directory manually
I would imagine that should remedy your entire issue
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'
}));