Im a beginner with node.js so bear with me please :D
Simple task: I use express and I want to send an array, lets say ["item1", "item2"] from a node server to a client that calls the server with a get method. When I tried this, I stumbled upon the CORS error.
I also thought about doing a this through a post:
-client:
$(document).ready(function () {
$(".testButton").click(function (e) {
e.preventDefault();
$.ajax({
url: "http://localhost:3000/test_post",
type: "post",
data: "sent",
success: function () {}
});
});
-server:
app.post('/Quiz_post', function (req, res) {
res.send(["item1", "item2"]);
});
But this also doesnt work. Now I am trying to use cross-fetch client side. Could you please guide me a bit? Thanks!
Add this code in ur app.js to enable CORS.
npm i cors in the project 1st
var cors = require('cors');
var app= express(); //After this line of code add the code below
app.use(cors());
Related
I'm learning Express and I face an issue which I can't understand.
When I route to /addPerson I expect to log the name: 'Mike', age: 30 to the console. Instead I got nothing logged to the console. What's wrong in my code?
here's the server.js code
const Express = require('express'),
app = Express(),
PORT = process.env.PORT || 5000,
parser = require('body-parser'),
data = []
// initialize the main project folder
app.use(Express.static('public'))
// running the server
app.listen(PORT, () => {
console.log(`Server is running at port ${PORT}`);
})
// include body parser to handle POST requests
app.use(parser.urlencoded({extended: false}))
app.use(parser.json())
// setup CORS
const cors = require('cors')
app.use(cors())
// GET request
app.get('/', (req, res) => {
res.send('<h1>Home Page</h1>')
})
app.get('/addPerson', (req, res) => {
res.send('<h1>Hello Hany</h1>')
})
// POST request
app.post('/addPerson', (req, res) => {
data.push(req.body)
console.log(data);
})
and here is the client side app.js code
const postData = async ( url = '', data = {})=>{
console.log(data);
const response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
// Body data type must match "Content-Type" header
body: JSON.stringify(data),
});
try {
const newData = await response.json();
console.log(newData);
return newData;
}catch(error) {
console.log("error", error);
}
}
postData('/addPerson', {name: 'Mike', age: 30});
this the files structure
Alright, I've taken a look at your code and this is what I've noticed. Within your server.js file you have this code block:
app.get('/addPerson', (req, res) => {
res.send('<h1>Hello Hany</h1>')
})
That is sending back a static H1 tag when the user creates a get request to localhost:5000/addPerson. Then, directly below that you have your post route but you're never fully accessing that from anywhere (I looked through all your app.js code to double check).
Instead, I have changed your code to return a static html file with a button that allows you to call this function (just as an example so you can see that your routes do in fact work). This isn't the cleanest solution to your problem but I just wanted to make sure you see where the problem lies as I've been in your shoes before when I first started working with express. You can take a look at the CodeSandbox I setup below to replicate your issue and take a look through all the code to get an understanding.
To properly solve your issue using the app.js file you would have to serve the javscript file as your "frontend". Personally I'm a big fan of React so I usually serve my frontend with React, while my backend is express. You can also very easily serve this file using NodeJS in a similar fashion that you are with your "backend". If you were to take the React approach you would be able to modify this code:
app.get("/addPerson", (req, res) => {
res.sendFile(path.resolve(__dirname, "public", "index.html"));
});
To find the frontend section you desire using React (I can recommend react-router if you require multiple routes but I don't want to overwhelm you with too much information yet) and complete the same function. If you have any questions feel free to reach out and let me know! Hopefully this helps!
I am setting up a sample App using Openui5 as frontend framework, Node.js & Express.js for backend API and MongoDB as database.
My JQuery Ajax post does not contain any body data when arriving at the backend.
I tried several of the solutions provided on stackoverflow, but none of them seems to work for me. MongoDB and Backend Server are running. Data fetching is also working with ui5 data binding to XML View.
controller.js:
onSave: function () {
//get user input from local json model
var oNewEmployee = this.getView().getModel("newEmp").getProperty("/newEmp"),
data = JSON.stringify(oNewEmployee),
url = 'http://localhost:3000/employee';
//do the post
$.ajax({
url : url,
dataType : 'json',
contentType : 'application/json',
data: data,
type : 'POST',
success: function(response){
console.log(response);
}
});
},
server.js:
var express = require("express");
var app = express();
var mongoose = require("mongoose");
var cors = require("cors");
app.use(cors());
mongoose.connect("mongodb://localhost/schichtplaner", { useNewUrlParser: true });
app.post("/employee", function (req, res) {
console.log(req.body);
});
app.listen(3000);
I keep getting undefined as output from console. Would be great if someone has an idea how to solve this.
You should use the body-parser npm module in order to read the POST request payload.
https://www.npmjs.com/package/body-parser
I am new and fail to make supertest work for me. I am wondering:
Why is the body undefined?
Is there a trick from the command line to show and inspect objects in the console?
Why doesn't the test logs "hello"?
"use strict";
const request = require('supertest');
const express = require('express');
const https = require('https');
const fs = require('fs');
const path = require('path');
const certPath = path.resolve(path.resolve(), './certs');
const app = express();
//This line is from the Node.js HTTPS documentation.
const options = {
key : fs.readFileSync(certPath+'/server-key.pem'),
cert : fs.readFileSync(certPath+'/server-crt.pem'),
ca : fs.readFileSync(certPath+'/ca-crt.pem')
};
// service
app.post('/failService', function(req, res) {
console.log('failService: '+req.body); // failService: undefined
res.send('hello');
});
describe('trial not working', function() {
it('responds with json', function(done) {
request(app)
.post('/failService')
.send({name: 'john'})
.set('Accept', /json/)
.expect(200)
.end(function(err, res) {
if (err) return done(err);
console.log('response: '+res.body); // response: [object Object]
done();
});
});
});
.... shows
$ mocha supertest.js
trial not working
failService: undefined
response: [object Object]
√ responds with json (125ms)
1 passing (171ms)
Please note that the certificates (not included) are self signed.
When isolating my code above I missed the options. As a result it does not use SSL. Sorry for that.
I fell back to starting the server and the use of a client in my test case. For that I had to fix:
CORS
The actual problem of this post by using a body parser
This is due to the self signed certificate.
i also faced similar issue there are two possible solutions
Create http server instead of https server for test environment
Replace supertest with superrequest npm package and set strictSsl as false.
So I'm running it on port 8080. Port forwarding has been set up and it is working.
Every time I type in my no-ip domain, I get the response on the screen but when I'm making a request from my website, it logs the request on the Raspberry, yet, there is no response visible in the Chrome developer tools.
I also get this error message: POST "name of the api" net::ERR_EMPTY_RESPONSE
What could cause that? My routes worked perfectly when I was running my api locally.
module.exports = function(app) {
app.get('/', requireAuth, function(req, res) {
res.send({ message: 'OMG, You made it, you deserve a drink!' });
});
That's how my react app looks like:
const ROOT_URL = *"name of the api"/*;
.
.
.
export function fetchMessage() {
return function(dispatch) {
axios.get(ROOT_URL, {
headers: { authorization: localStorage.getItem('token') }
})
.then(response => {
dispatch({
type: FETCH_MESSAGE,
payload: response.data.message
});
});
}
};
Is it a typical problem of the Node.js, Express, React or maybe it's on the Raspi? Thanks a lot!
Possibly a CORS issue, since the problem only happens when trying to consume the API from the browser. A possible solution is to use the cors package in your Express application:
const express = require('express');
const cors = require('cors');
...
const app = express();
app.use(cors());
...
NOTE: this enables all CORS requests.
I am trying to capture current GET URL and query params in node.js code. I jut realized windows.loication does not work in node.js as it is for client-based execution only. I have tried multiple things but am not able to capture the GET request. Here is what all I have tried.
var url = require('url');
var url_parts = url.parse(request.url, true);
var query = url_parts.query;
var request = require('request');
var query = url.parse(request.url,true).query;
getFormattedUrl(req);
function getFormattedUrl(req) {
console.log("req.url: " + req.url);
return url.format({
protocol: req.protocol,
host: req.get('host')
});
}
All of these fail for me, giving the errors like :
2016-12-17T03:32:36.164600+00:00 app[web.1]: ReferenceError: request is not defined
2016-12-17T03:43:46.569603+00:00 app[web.1]: ReferenceError: request is not defined
2016-12-17T03:45:14.509168+00:00 app[web.1]: TypeError: Parameter 'url' must be a string, not undefined
Can someone pls suggest how to cpature the GET params in node.js.
If you are using express 4.x then you want req.query
If you are trying to capture the request that is being made from a NODE JS server to another http/https endpoint for debugging or viewing purposes, this might help
var options2 = {
url: "https://www.google.com",
port: '443',
method: 'GET'
}
request(options2, function(error, response){
console.log(options2);
});
where options2 is the defined URL the node js server is trying to reach
When you console log options2 (a variable name i've used, you can call it anything), it will give you all the information about the HTTPS/HTTP call the server is making.
Sample Express JS 4 Code
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Someting')
console.log(req.query);
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
This will launch a localhost server on port 3000
If you do localhost:3000?q=test you will see
{q: test}
in the console/log.
To fix the problem above, just install request module from the command line first, before using it:
npm install request
Interesting things is that to achieve what you need, you do not need to use request module at all. Just use url module as you did above, pass request object (not a module, but actual calling request), and format it using url.format
const url = require('url')
function getFormattedUrl(req) { return url.format(req.url) }