I'm trying to post to Heroku from localhost. Here is the sample script at the JavaScript localhost server:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
axios.post('https://thawing-meadow-45314.herokuapp.com', {}).then(res =>{ //perform operation }) .catch(err=>{ // handel error here. })
Here is Node.js script running on Heroku:
const express = require('express');
const app = express();
const cors = require("cors");
app.use(cors());
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.post('/', (req, res) => {
console.log('message is delivered');
}); //app.post
const port = process.env.PORT || 3081;
app.listen(port, () => {
console.log(`Server running on port${port}`);
});
On the command line I use three commands:
Heroku login
Heroku run bash
node index.js
The problem is that nothing happens. Heroku app isn't detecting my post request from the localhost. What I have to do?
axios.post('https://thawing-meadow-45314.herokuapp.com:55058', {})
Don't post to the port Heroku gives you via the PORT environment variables.
That's the internal port your app needs to bind to, but this is exposed publicly as the standard ports 80 and 443. Leave the port out entirely:
axios.post('https://thawing-meadow-45314.herokuapp.com', {})
Also, don't do this:
On the command line I use three commands:
heroku login
heroku run bash
node index.js
Your server should start up automatically via the start script in your package.json (or a custom command given in your Procfile). Something like
"scripts": {
"start": "node index.js"
}
in your package.json should do it. Heroku dynos restart frequently, so it's important that they can start up on their own.
Remove PORT from Axios request URL.
axios.post('https://thawing-meadow-45314.herokuapp.com', {}).then(res =>{
//perform operation
})
.catch(err=>{
// handel error here.
})
Also, make sure you have enabled CORS on your server. I`ll suggest using cors module if you are not using it and add it to your app middleware like this:
const express = require("express");
const app = express();
const cors = require("cors");
app.use(cors());
app.post("/", (req, res) => {
// perform operation and return response.
res.status(200).json({ message: "It worked!" });
});
app.listen(3000, function() {
console.log("server is running");
});
And don`t forget to restart the server after making changes.
Related
I recently deployed a website for the first time ever. We have 2 servers, so to say: 'https://baseUrl.com' and 'https://api.baseUrl.com' to make requests.
When trying to submit a contact form the data uploads to mongoDB but it isn't sent to node.js or from node.js it isn't sent to our e-mail address via nodemailer (I don't know exactly) and I get this error: Access to XMLHttpRequest at 'https://api.baseUrl.com' from origin 'https://baseUrl.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I do not have access to the nginx server but I was told that the specific CORS header/s have been set.
What should I do? Is there anything I could write in my code to fix this or it's strictly a server issue?
For example, I tried adding this code on node.js but it didn't help
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "YOUR-DOMAIN.TLD"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Example of code that is not executed because of the CORS error:
app.post('/api/*endpoint*',(req,res) => {
upload(req,res,function(err){
if(err){
return res.end("Something went wrong!");
}else{
let mailOptions = {
from: req.body.email,
to: '*email*',
};
transporter.sendMail(mailOptions, function(err) {
if (err) {
return res(err);
}
})
}
})
});
you can use cors express middleware to avoid cors troubles. Sample usage is below. Before using, you have to install npm package by typing "npm i cors"
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
From my front-end, I am attempting to get data from the backend running at port 5000. I am not sure if the port is supposed to be running before running the react app. However, I tried both situations, I ran the backend port 5000 on a different terminal, and then the frontend on a different terminal. Do I actually use a request or response with the get method for axios? Please, is there anything wrong with my code?
This is my frontend
import React, {useState} from 'react';
import axios from "axios";
const Quotes = () => {
const [text, setText] = useState("");
const [author, setAuthor] = useState("");
function getQuote(){
axios.get("https://localhost:5000/", { crossdomain: true }).then(response => {
setText(response.data.text);
setAuthor(response.data.author);
});
}
return (
<div>
<button onClick={getQuote}> Generate Quote</button>
<h1>{text}</h1>
<h3>{"-" + author}</h3>
</div>
)
}
export default Quotes;
So, over here, I am attempting to send API data with express to the homepage. And I am struggling to understand why it is not appearing on the front-end.
This is my backend
const express = require("express");
const quote = require('inspirational-quotes');
const app = express();
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("/", function(req, res){ // quotes is send to the homepage of app
res.send(quote.getQuote());
});
let port = process.env.PORT;
if (port == null || port == ""){
port = 5000;
}
app.listen(port, () =>{
console.log("Server is running...");
});
I get the data when I run the backend on port 5000, but I don't get it to display on the react app. Please help.
I resolved my bug. I had to debug it from the browser console. I realized I used https for localhost. It was the wrong URL protocol.
I corrected it by changing https://localhost:5000/ to http://localhost:5000/
I have a next.js app and I'm trying to create an api. When I run it as development, the api's get called, but when I run it using next start I get a 404 error when calling the api's.
Here's the relevant server.js code:
app.prepare().then(() => {
require('./server/startup/routes')(server);
server.get('*', (req, res) => {
return handle(req, res);
});
const PORT = process.env.PORT || 5000;
server.listen(PORT, err => {
if (err) throw err;
console.log(`> Read on http://localhost:${PORT}`);
});
});
Here's the routes file
module.exports = app => {
app.use('/api/something-cool', cool);
};
Cool File:
const express = require('express');
const router = express.Router();
router.post('/', async (req, res) => {
...Code
res.send({ status: 'ok' });
});
module.exports = router;
The api route of /something-cool works when I run nodemon, but when I run next run, it returns a 404 error. What am I doing wrong and how can I fix it?
You are using a custom server (express) on top of Next.js to customize routes. This means that first, you have to build the Next.js App and then you have to run your server.js file in order to serve the App.
Option 1:
Builds the production application first
next build
Then run you server.js file:
NODE_ENV=production node server.js
more info here https://github.com/zeit/next.js/tree/master/examples/custom-server-express
Option 2:
There is also the option to create the API route within the Next.js App without using a custom server.
See https://github.com/zeit/next.js/tree/master/examples/api-routes for more info on how to do it.
I'm working on my first website, and am using axios to send post/get requests to the backend. I'm using React on the front-end and node/express on the back-end. I'm wondering if there is a way to prevent posts from a source other than my site.
For example, if I make this exact request through postman I am still be able to post comments, meaning that someone could post with names and ID's other than themselves.
Here is a typical post request made on the front-end:
axios.post('/api/forumActions/postComment', {}, {
params: {
postUserID: this.props.auth.user.id,
name: `${this.props.auth.user.firstName} ${this.props.auth.user.lastName}`,
commentContent: this.state.commentContent,
respondingToPost: this.state.postID,
respondingToComment: this.state.postID
}
})
And here is how it gets processed on the back-end
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
app.use(passport.initialize());
require("./config/passport")(passport);
app.post('/postComment', (req, res)=>{
var commentData={
postUserID: req.query.postUserID,
name: req.query.name,
commentContent: req.query.commentContent,
respondingToPost: req.query.respondingToPost,
respondingToComment: req.query,respondingToComment
}
//Write commentData to database
})
const port = process.env.PORT || 80;
const server = app.listen(port, () => console.log(`Server running on port ${port} !`));
I'm wondering if there is anything I can do to ramp up security to prevent post requests being made from anywhere?
You can use cors to accomplish this. This is a pretty good guide on how to configure it, specifically this section. You can configure it for certain routes, or all across the board.
CORS sets the Access-Control-Allow-Origin header, which you can read more about here - it only allows requests from specified origins.
Keep in mind you don't need that package to accomplish this.. you could always build your own middleware for this.
Something like:
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "http://yourdomain.com");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Within the Express documentation, they provide the following demo code, which you should be able to use as a helper.
Client
Server
You could use a makeshift middleware with special headers.. but then all someone has to do is read your client side source code, or look at the network tab in their browser to figure out which headers you're sending, so then can duplicate them. It would prevent random people from snooping, though..
const express = require('express');
const path = require('path');
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Custom special middleware..
function blockBadHosts({ host, whitelistHeader, whitelistHeaderValue }) {
return (req, res, next) => {
if(req.headers['host'] === host) {
if(whitelistHeader && req.headers[whitelistHeader] === whitelistHeaderValue) {
next();
} else {
res.status(301).send('BAD REQUEST');
}
} else {
res.status(301).send("BAD REQUEST");
}
}
}
// Options for our custom middleware
const badHostOptions = {
host: "localhost:3000",
whitelistHeader: "x-my-special-header", // Request must contain this header..
whitelistHeaderValue: "zoo" // .. with this value
}
// This should succeed
app.get('/success', (req, res) => {
res.status(200).send("from /success");
});
// This should fail even if sent from Postman without correct headers
app.get('/failure', blockBadHosts(badHostOptions), (req, res) => {
res.status(200).send("from /failure");
});
// 404 route
app.use((req, res) => {
res.status(404).send("Uh oh can't find that");
})
app.listen(port, () => {
console.log(`App listening on port: '${port}'`);
});
So I'm using webpack for a project on 8080 with a backend on 3000. The proxy seems to work fine, as I can send requests to the backend and access it without issue. However. I need to include this middleware that allows me to have a user load the page, and if they've logged in within a certain amount of time, the initial request they send to the server logs them in automatically.
router.use(function (req, res, next) {
//check token for routes beneath vvvv
})
router.post('/preauth', function (req, res) {
//return user account info if req.token is valid
})
When I try to get to prauth, or even any route before that from the page loaded on 8080 I only touch the middleware and nothing else.
When I do npm run build then try it again from the identical page on 3000, it works as expected.
No, CORS is not enabled and the proxy does not rewrite any url.
Does anyone know if something in my Webpack config might be causing this?
You need install Cors in nodejs:npm install cors, you can try the following below or you see: Nodejs + Vuejs
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(80, function () {
console.log('This is a CORS-enabled web server listening on port 80')
})