I'm doing an university project with NodeJs but I have some trouble in testing it in local.
This is the problem:
I have a GET API "/api/services/names" and the NodeJS server is running on port 8080.
If I test the API with Postmanor by putting the URL in the Chrome bar ("http://localhost:8080/api/services/names") it works fine and I can get my response.
The problem is that if I test it in my local website using fetch() inside this function:
function fetchServicesNames(){
fetch('/api/services/names')
.then(function(response){
return response.json();
})
.then(function(data){
data.map(addServiceLink);
});
}
The Javascript console gives me this error:
Failed to load resource: the server responded with a status of 404 (Not Found)
I noticed that when I hover the console error, it shows the request string "http://localhost/api/services/names" without the port. But I don't think this is the problem because when I deploy the application on the Heroku platform it works fine... the problem is just in localhost (I'm working with a mid 2010 macbook pro with Mac OSX 10.10.2).
Any help is appreciated, thank you in advance.
Edit:
as requested I'm adding here the server code
// server.js for Hypermedia Application project.
// BASE SETUP
//============================================================
// call packages
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(express.static(__dirname + "/public"));
// we use body-parser, so we need to be able to read data either from
// GET and POST:
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// setting the application port to listen
var serverPort = process.env.PORT || 5000;
// --- database connection omitted ---
// API ROUTES
// ================================================================
// first of all: get the Router
var router = express.Router();
/**
* Services names
* /api/services/names - get - get all services ids and names
*/
router.route('/services/names')
.get(function (req, res) {
Service.find({}, 'id name', function (err, services) {
if (err)
res.send(err);
res.json(services);
});
});
// --- Other APIs omitted ---
// REGISTER ROUTES:
// all of our routes will be prefixed with /api
app.use('/api', router);
// START THE SERVER
//===================================================================
app.set("port", serverPort);
app.listen(serverPort, function() {
console.log(`Your app is ready at port ${serverPort}`);
});
at your server page you add
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
before your API's
it might help you for CORS
Dear i suggest you to write total Path like
http://localhost:<your port number>/api/services/names
inside fetch()and u check once
I too tried and i got Success
Hi try modifying the line like fetch('http://'+window.location.host+':8080/api/services/...)
Related
Could you help me solve this error? It seems that I can not connect between server.js and app.js.
What I want to do is: display the result of the postData('/add', {answer:42}); and postData('/addMovie', {movie:'the matrix', score:5}); in the console.
Thank you for your help in advance.
error image
server.js
// Setup empty JS object to act as endpoint for all routes
projectData = {};
// Require Express to run server and routes
const express = require('express');//add
// Start up an instance of app
const app = express();//add
/* Dependencies */
const bodyParser = require('body-parser') //add
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
//we can connect the other packages we have installed on the command line to our app in our code with the .use() method
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');//add
app.use(cors());//add
// Initialize the main project folder
app.use(express.static('website'));
////////////////////creating a local server
const port = 5500;//add
// Setup Server
//////////////////////add
const server = app.listen(port, listening);
function listening(){
// console.log(server);
console.log(`running on localhost: ${port}`);
};
app.get('/all', function (req, res) {
res.send(projectData)
})
// POST route
const data = []
app.post('/add', callBack);
function callBack(req,res){
res.send('POST received');
console.log(data)
}
const movieData = []
app.post('/addMovie', addMovie )
function addMovie (req, res){
movieData.push(req.body)
console.log(movieData);
}
app.js
app.js
[Addition]
Thank you for your feedback!!
I changed the port in server.js, but nothing changed.
port5500
The issue was resolved.
// when using local server ( ≒ server.js in this case)
postData('/add', {answer:42});
postData('/addMovie', {movie:'the matrix', score:5});
// when using live server
postData('http://localhost:5500/add', {answer:42});
postData('http://localhost:5500/addMovie', {movie:'the matrix', score:5});
You need to add an "allow" in the header field to support this or explicitly allow it in your webserver configuration
A lot of the time, this is set up in the configuration of your .htaccess or nginx.conf file (depending on the webserver). It will commonly be found in your RewriteRule section. You can look for a "R=405" flag there.
I recently purchased a VPS from OVH for the hosting of my discord bot. It has a stats.json page that I need to have another site GET to, but I can't seem to find my VPS's express site.
I'm trying to access it from my vpsXXXXXX.vps.ovh.ca, but I get the error: This site can’t be reached. I have the following on my main code:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.get("/", (request, response) => {
response.sendStatus(200);
});
app.get('/stats', function(request, response) {
response.sendFile(__dirname + "/stats.json");
});
And even with this code, I get no response from the VPS's URL.
I'd want to have my glitch.me site to be able to GET the data from the stats.json, but I can't seem to find or figure out a way to get a URL for my VPS.
Does anyone know how to connect a URL or use the VPS URL?
Thank You!
Codingpro
You forgot to listen. Set the environment port instead
var port = process.env.PORT || 3000
app.listen(port, () => console.log(`Online on port ${port}!`))
I figured out my issue:
I had forgotten to add the app.listen() to the code. Here is what I added to fix it:
var port = 3000
/*
* Set your server's port. This made mine vpsXXXXXX.vps.ovh.ca:3000.
* HTTP standard port: 80
* HTTPS standard port: 443
*/
app.listen(port, () => console.log(`Online on port ${port}!`))
I've got a React app that via an API pulls data from a separate database.
When I run it locally, the app is one port and the API is on another port.
Since when I make AJAX calls in the app to the API, I need to include the URL where the API can connect.
It works if I hardcode the separate port (e.g., the app is on http://localhost:3000 and the API on http://localhost:3100, making the AJAX url call to the API http://localhost:3100/api/trusts).
However, since the app and API are on different ports, I can't make the AJAX url a relative path because it erroneously sends the AJAX call to http://localhost:3000/api/trusts and not http://localhost:3100/api/trusts.
How do I get them to run on the same port?
Thanks!
Here's my server.js:
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var path = require('path');
var app = express();
var router = express.Router();
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//set our port to either a predetermined port number if you have set it up, or 3001
var port = process.env.PORT || 5656;
//db config
var mongoDB = 'mongodb://XXX:XXX!#XXX.mlab.com:XXX/XXX';
mongoose.connect(mongoDB);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
//body parsing
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// allow cross-browser
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
next();
});
// handling static assets
app.use(express.static(path.join(__dirname, 'build')));
// api handling
var TrustsSchema = new Schema({
id: String,
name: String
});
var Trust = mongoose.model('Trust', TrustsSchema);
const trustRouter = express.Router();
trustRouter
.get('/', (req,res) => {
Trust.find(function(err, trusts) {
if (err) {
res.send(err);
}
res.json(trusts)
});
});
app.use('/api/trusts', trustRouter);
//now we can set the route path & initialize the API
router.get('/', function(req, res) {
res.json({ message: 'API Initialized!'});
});
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(port, function() {
console.log(`api running on port ${port}`);
});
Below is the AJAX call I'm trying to make that doesn't work because the relative path is appended to the app's port (i.e., http://localhost:3000/) and not the API's port (i.e., http://localhost:3100/):
axios.get("/api/trusts")
.then(res => {
this.setState({trusts: res.data});
})
.catch(console.error);
To tell the development server to proxy any unknown requests to your API server in development, add a proxy field to your package.json, for example:
"proxy": "http://localhost:4000",
This way, when you fetch('/api/todos') in development, the development server will recognize that it’s not a static asset, and will proxy your request to http://localhost:4000/api/todos as a fallback. The development server will only attempt to send requests without text/html in its Accept header to the proxy.
"Keep in mind that proxy only has effect in development (with npm start), and it is up to you to ensure that URLs like /api/todos point to the right thing in production."
Note: this feature is available with react-scripts#0.2.3 and higher.
More details here: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#proxying-api-requests-in-development
I'm not new to JavaScript but I am new to Node.js and back end languages. I have a very simple question.
I've installed and setup Node.js on my computer and I'm attempting to get a server going between my static files & directory(s) and my browser to be able to send and receive requests. I've downloaded Braintree's free Sandbox (found here) for practice to get some faux transactions going just to gain a better understanding of how this can work.
I set up a local server by running npm install -g http-server on my command line and then http-server to set it up.
I then received the following message in my command line:
Starting up http-server, serving ./public
Available on:
http://127.0.0.1:8080
http://10.0.1.4:8080
Hit CTRL-C to stop the server
So, with this setup...if I wanted to do get() and post() methods and see it rendered and communicating between my "server" and my static files. How do I do this? For example, if I were to set up Braintree's sandboxed environment and then create a clientToken using the following code from Braintree's website
const http = require('http'),
url = require('url'),
fs = require('fs'),
express = require('express'),
braintree = require('braintree');
const gateway = braintree.connect({
environment: braintree.Environment.Sandbox,
merchantId: "xxxxx",
publicKey: "xxxxx",
privateKey: "xxxxx" //blocked out real numbers for privacy
});
Here is the remaining code I hae to create a "client Token" for a transaction...and here is the guide I'm following via Braintree's website...
http.createServer((req,res) => {
gateway.clientToken.generate({
},(err, response) => {
if(err){
throw new Error(err);
}
if(response.success){
var clientToken = response.clientToken
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(clientToken);
res.end("<p>This is the end</p>");
} else {
res.writeHead(500, {'Content-Type': 'text/html'});
res.end('Whoops! Something went wrong.');
}
});
}).listen(8080,'127.0.0.1');
So, my question is...if I wanted to generate send a token to a client using the get() method...how would I do that? Would it have to be a separate js file? How would they be linked? If they're in the same directory will they just see each other?
Here is an example on Braintree's website of how a client token may be sent:
app.get("/client_token", function (req, res) {
gateway.clientToken.generate({}, function (err, response) {
res.send(response.clientToken);
});
});
How could this be integrated into my current code and actually work? I apologize if these are elementary questions, but I would like to gain a better understanding of this. Thanks a lot in advance!
I don't know much about braintree, but usually you would use somthing like express.js to handel stuff like this. So I'll give you some quick examples from an app I have.
#!/usr/bin/env node
var http = require('http');
var app = require('../server.js');
var models = require("../models");
models.sync(function () {
var server = http.createServer(app);
server.listen(4242, function(){
console.log(4242);
});
});
So that's the file that gets everything started. Don't worry about models, its just syncing the db.
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
// share public folder
app.use(express.static(path.join(__dirname, 'public')));
require('./router.js')(app);
module.exports = app;
next up is the server.js that ties eveything together. app.use() lines are for adding middleware and the app.use(logger('dev')); sets the route logger for what your looking for.
app.use(express.static(path.join(__dirname, 'public'))); shares out all files in the public directory and is what your looking for for static files
var path = require('path');
module.exports = function(app){
//catch
app.get('*', function(req, res){
res.sendFile(path.join(__dirname, '..', 'public', 'index.html'));
});
}
last piece is the router.js. This is were you would put all of you get and post routes. generally I've found that if you see app.get or app.post in examples there talking about express stuff. It's used a lot with node and just makes routing way easier.
Also if your using tokens a route would look like this.
app.get('/print', checkToken, function(req, res){
print.getPrinters(function(err, result){
response(err, result, req, res);
});
});
function checkToken(req, res, next){
models.Tokens.findOne({value: req.headers.token}, function(err, result){
if(err){
res.status(500).send(err);
}else if(result == null){
console.log(req.headers);
res.status(401).send('unauthorized');
}else{
next();
}
});
}
so any route you want to make sure had a token you would just pass that function into it. again models is for db
I'm using the body-parser npm package to parse POST data in Application/JSON format and using a few different express routers to modularize the routes I'm creating. Here's the important info in my main server.js file:
server.js
var express = require('express');
var bodyParser = require('body-parser');
app.use(bodyParser.json());
// I'm using a sessionId to identify a person in this dummy app instead of adding in authentication. So the API call is sent to http://localhost:5000/johndoe/todo
app.use('/:sessionId/todo', require('./routes/todoRoutes'));
var port = process.env.PORT || 9191;
app.listen(port, function () {
console.log('Express server listening on port ' + port);
});
todoRoutes.js:
var todoRouter = require('express').Router();
todoRouter.post('/', function (req, res) {
console.log("This is the post data:");
console.log(req.body);
});
module.exports = todoRouter;
req.body seems to be getting lost through the middleware; it logs {} to the console. However, on a whim I added the following to my bodyParsing middleware in server.js:
app.use(bodyParser.json(), function (req, res, next) {
next();
});
And now it's passing req.body through to todoRoutes.js. (It now logs {title: 'Testing'}, etc. to the console like I need it to.)
What's going on here? And what's the best way to structure this so that it works the way it's supposed to? I'm new to Express, so I admit I could be structuring this all wrong.
Ugh, nevermind. I was an idiot and found that the Content-Type Header of application/JSON got turned off in Postman (read: I must have turned it off at some point) and so the bodyParser was never being used.
Dammit.
Thanks for the help to those who responded!