I've recently been playing with nodejs and would like to build my first project with it. But there is a major stumbling block for me.
URL Generation.
I'm very used to Codeigniter's base_url() and site_url(), this gave a full url like http://www.example.com/resources/img/bla.jpg, so it's been a bit odd for me to find that there is no such equivalent functions for NodeJS / Express.
Am I going about this wrong or is there a module somewhere that would make it possible to generate urls much like base_url() and site_url() did?
I'm using the Express Framework with Jade as the template engine and MongoDB as the Database.
The scope of Express and the scope of a PHP framework like Codeigniter are quite different, and Express makes much less assumptions on how your site is laid oud. For example, it would be perfectly possible to serve several virtual hosts with Express (using the connect-vhost middleware). In this case there would be little point in having a function like base_url().
This being said, it would be quite easy to roll your own, something like that:
var BASE_URL = "http://mysite.com"; // Can be loaded in a config file
module.exports.baseUrl = function(path) {
path = (path || "").replace(/^\//, '');
return BASE_URL + "/" + path;
}
Related
I have a project by Three.js.
Like below pic, i have an index.html that uses js codes from scripts.js (in sub-Directory of js).
also, this scripts.js , uses three and OrbitControls libs of package of three.js.
PROBLEM:
after running my project, browser, shows HTML and CSS fine, but it do not works by javascript and gives this error:
i can't find any solution, after half a Day searching & manipulating!
can any one help please?
1)project structure:
root
|------server.js
|------/public
| |---index.html
| |---/js/scripts.js
| |---/css/index.css
2)root/public/index.html:
3)root/public/js/scripts.js:
4)root/server.js:
const express = require("express");
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, '/public')));
app.get('/',function(req,res) {
res.sendFile("public/index.html")
});
app.listen(3000, () => {console.log("listening on port 3000");});
Multiple things going on here. First, require() is nodejs ONLY, is not present in the browser. You are trying to load and run js/scripts.js in the browser and thus cannot use require() in that script.
Separately, when you use type="module" in a script tag, that means the module is an ESM module which can use import to load other modules, but import needs to specify a URL that your express server will handle and serve the right file with.
I'm also guessing that you will have a problem loading the script files because they need to be served by express.static() in your server and need to have the appropriate URL paths in your web page so that express.static() will work. You don't show the server-side file structure for all those scripts so it's hard for us to know exactly what the URLs should be.
And, in the future, please don't ever post screen shots of code. That makes it a lot harder for us to use your code in tests or in answers (because we have to retype it all from scratch) and it can't be searched, is harder to read on mobile, etc... Don't put code in images.
I have a expressJs setup which looks like this:
// Imports...
const app: express.Application = express();
const port: number = 3001;
const listener = new StatementListenerAPI();
app.use('/listen', listener.getRouter());
app.use('/welcome', router);
if (fs.existsSync('./client')) {
// Running in prod environment with pre built client directory. Serve this.
app.use(express.static('./client'));
}
app.listen(port);
So I have some routers connected to the express app, and at the bottom I declare that the directory client should be served statically. This directory contains an index.html as well as lots of JS, CSS and PNG files. However, no matter which URL I try to access from the express server, it always shows the code of the index.html within the statically served directory. The references to the JS and CSS files used inside the index.html also just return the code of the index.html.
I am using ExpressJS 4.16.3
What am I doing wrong?
Edit: So technically it works if using __dirname + '/client' instead of ./client. What I am now getting is that, when making GET requests from e.g. Postman (therefore "hand-crafting" the HTTP requests), I am always getting the correct results. If I call the resources from within my web browser, it still always shows the website (resolves the index.html). However, now all resources like JS and CSS scripts are being resolved properly, so apperantly Chrome resolves those dependencies properly, I am just wondering why I am still getting the contents of index.html as result when requesting some of the assets or some of the express endpoints via Chrome. API calls via code are working fine, so its only why manual chrome requests show this weird behaviour, at this point I am only asking out of curiosity.
Answer to your original question:
The path supplied to express.static should be relative to the directory from where you launch your node process or an absolute path. To be safe construct an absolute path (ie from the current directory or file). For example:
app.use(express.static(__dirname + '/client'));
Regarding your followup question:
I assume this is because Chrome uses heavy caching and it thinks this folder should return the html file. You can try and reset all caches in Chrome, or just for the page.
Newbie question: I'd like to use Node's URL module (http://nodejs.org/api/url.html) in AngularJS.
e.g.
var url = require('url')
url.resolve('http://example.com/', '/one')
How do I do that?
You have a couple options.
You could use something like Browserify, or you could simply use a different library meant for URL manipulation in the browser.
URI.js comes to mind.
I have frontend content that needs backend REST APIs to function. The APIs allow for cross-origin resource sharing (CORS). Typically we run the complete stack locally, including a user-mode Nginx instance tailored for development use which serves the frontend content. The full stack however is a bit too much to expect part time contractors to wrangle. So I'd like an approach very basic they can use to be effective and get stuff done.
Their current solution is horrible:
var port = location.port;
// base url of backend API
var url = window.location['origin'];
if (port != '443') {
// assume we're running in "development" mode against a staging server
url = "https://staging-server.somewhere.com";
}
Apart from the fact that this is furthering frontend content that is a bit kludgey as it is - it precludes the static content from being hosted in a variety of other ways, including a suite of functional and integration tests.
I have some ideas, like having them run a small web server that proxies to the backend APIs, but what I would really like is something simpler that allows me to default url in a less kludgey way. Ideally, there would be some manner of configuring url from a file ignored by version control (e.g., .gitignore).
I was able to create a solution that works for all manner of local development as well as production releases.
I created some JavaScript, apiurl.js, that sits alongside all of our other JavaScript content. If the apiurl.jsfile is present, I read its responseText into eval(). The frontend can therefore change the URL based on the content of that file.
E.g., apiurl.js has:
var apiurl = "https://staging-server.somewhere.com";
And the JavaScript to handle the content:
eval(responseText);
if (typeof(apiurl) != undefined) {
url = apiurl;
}
The apiurl.js file is untracked by version control and not used in production.
I never thought this would be a problem with Node.js and Express, but on a crazy whim I decided to type into a browser the location of one of the source files in my Node.js Express project - something like:
http://www.mywebsite.com/mynodejsapp/app.js
To my extreme horror, my application's source code popped right up, publicly available for all to see.
So, that aside: how do I stop it in Node.js / Express?
My setup code is pretty straightforward:
var app = express();
app.configure(function() {
app.use(express.static('/home/prod/server/app/public'));
});
app.listen(8888);
To clarify, this is what my folder structure looks like:
/home/prod/server/
/home/prod/server/app.js
/home/prod/server/public/
All sorts of various files that are intended for public access live under /public. All of my server source code lives under /server/, and my understanding of Express's static folder configuration is that the static folder is the only place that Express happily serves up files from the filesystem from.
Any ideas?
From what you posted it really smells like the URL you entered is served by e.g. Apache/nginx/... and you did put your node app within the document root. The answer is simple in this (and any similar) case:
You never put any of your sourcecode files within the document root or another HTTP-accessible folder. In your case, /home/prod/server/app/public should contain only client-side stuff (HTML, CSS, Graphics, (minified) client-side JS) and nginx should not have anything above this folder as its document root.