I'm using MERN Stack and everything was working fine until I made some changes to the UI (Moving code to different components, changing styles,...).
I didn't change any code in the Axios request and only this POST request doesn't work, the other requests work normally.
I have already setup CORS in my backend
I can access
my-project.herokuapp.com/insertlink and there's no error in the Heroku logs. No error thrown in the client or server terminal.When I click on the Add To List button in the form, the
addToListfunction which contains the Axios POST request doesn't send the data to the database like it used to.
- After 30 seconds - this error appears:
Please help me understand what is going on and how to fix this. I have looked for other solutions but I don't know how to apply to my case. Thank you! :)
Here's my code:
addToList function on the client-side:
const addToList = async (event) => {
event.preventDefault()
try {
await Axios.post(
"https://my-project.herokuapp.com/insert",
{
foodName: foodName,
isVegetarian: isVegetarian,
priceRange: priceRange,
foodUrl: foodUrl,
}
)
.then(() => {
setFoodName('')
setIsVegetarian('')
setPriceRange('$')
setFoodUrl('')
})
} catch(err) {
console.error(`The error is ${err}`)
}
}
Dinner.js - Mongoose Schema
const mongoose = require('mongoose')
const DinnerSchema = new mongoose.Schema({
foodName: {
type: String,
required: true,
},
isVegetarian: {
type: String,
required: true,
},
priceRange: {
type: String,
required: true,
},
foodUrl: {
type: String,
required: true,
}
})
const Dinner = mongoose.model("dinners", DinnerSchema)
module.exports = Dinner
Server's index.js and the endpoint that doesn't work:
const express = require("express")
const mongoose = require("mongoose")
const cors = require('cors')
const app = express()
require("dotenv").config()
const DinnerModel = require('./models/Dinner')
app.use(express.json())
app.use(cors())
// Connect to MongoDB
mongoose.connect(
'mongodb srv://linktoDB',
{
useNewUrlParser: true,
}
)
// Create:
app.post("/insert", async (req, res) => {
const foodName = req.body.foodName
const isVegetarian = req.body.isVegetarian
const priceRange = req.body.priceRange
const foodUrl = req.body.foodUrl
const dinner = new DinnerModel(
{
foodName: foodName,
isVegetarian: isVegetarian,
priceRange: priceRange,
foodUrl: foodUrl
}
)
try {
await dinner.save()
res.send("Inserted successfully")
} catch(err) {
console.log(err)
}
})
// Creating a port:
app.listen(process.env.PORT || 3001, () => {
console.log("Server is connected.")
})
My backend's package.json:
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"engines": {
"node": "12.20.1"
},
"scripts": {
"start": "node index.js",
"devStart": "nodemon index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.2",
"mongoose": "^6.1.3",
"nodemon": "^2.0.15",
"validator": "^13.7.0"
}
}
UPDATE
I added this code and it still doesn't work:
const corsOptions = { "origin": "*", "methods": "GET,HEAD,PUT,PATCH,POST,DELETE", "preflightContinue": false, "optionsSuccessStatus": 204, "allowedHeaders": ["Content-Type"], }app.use(cors(corsOptions))
Here's the preflight request and response when I try to add the document. One with status 204 and one with status 503:

CodePudding user response:
Problem
According to Axios's source code, if the second argument to Axios.post is an object, Axios sets the request's content type to application/json. This value is such that, according to the Fetch standard, the Content-Type header must be allowed by the server for CORS preflight to succeed.
However, you're relying on Express.js's CORS middleware's default configuration,
app.use(cors())
and that default configuration doesn't allow any request header.
Solution
Allow the Content-Type request header in your CORS configuration:
const corsOptions = {
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204,
"allowedHeaders": ["Content-Type"]
}
app.use(cors(corsOptions))
CodePudding user response:
I have found what caused the 503 Error when checking for the Payload of the POST request in the Network tab.
It was receiving an empty string for my
isVegetarianvalue.That empty string happened because I changed the
isVegetarianschema type from Boolean to String but forgot to change the initial state to a specific value:const [isVegetarian, setIsVegetarian] = useState('')In the Schema, I set isVegetarian to required: true so it won't accept empty strings.
-> So if you have the CORS config right and still have the same 503 error. Maybe check for the Network tab for preflight requests, response & payload to see if there's any leftover code you need to review.


