I am trying to connect my react application to MySql database using nodejs but on clicking the submit button it throws me the following error:
POST http://localhost:3000/login 500 (Internal Server Error)
Failed to load http://localhost:3000/login: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 500. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Uncaught (in promise) TypeError: Failed to fetch
Below is my code for my login component and my nodejs file.
Login.js:
import React from "react";
import {Header} from './Header';
export class Login extends React.Component{
constructor() {
super();
this.state = { user: {} };
this.onSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
//const proxyurl = "https://cors-anywhere.herokuapp.com/";
var self = this;
// On submit of the form, send a POST request with the data to the server.
fetch('http://localhost:3000/login', {
method: 'POST',
body: {
name: self.refs.name,
job: self.refs.job
}
})
.then(function(response) {
return response.json()
}).then(function(body) {
console.log(body);
});
}
render(){
return(
<div>
<div id="fm">
<form onSubmit={this.onSubmit} >
<div >
<label>
Username:
<input id="uname" type="text" placeholder="Name" ref="name"/>
</label>
</div>
<div >
<label>
Password:
<input id="upass" type="password" placeholder="Jo b" ref="job"/>
</label>
</div>
<input id="sub" type="submit" value="Submit" />
</form>
</div>
</div>
);
}
}
Connection.js:
var mysql = require('mysql');
var express = require('express');
var app = express();
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "react"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
//var sql = "INSERT INTO users (name, job) VALUES ('e211', 'Highway 37')";
//con.query(sql, function (err, result) {
//if (err) throw err;
//console.log("1 record inserted");
//});
});
app.post('/login', function(req, res) {
// Get sent data.
var user = req.body;
// Do a MySQL query.
var query = con.query('INSERT INTO users SET ?', user, function(err, result)
{
// Neat!
});
res.end('Success');
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
});
On running Connection.js it connects to my database and if I try to insert data directly by writing an insert statement in the Connection.js file and running it, then it inserts into database but if I try to click on submit button on my UI it throws the above error.
Can someone tell me where I have gone wrong and guide me on the same?
You will need to enable CORS on the server this is to avoid any unwanted calls to your server API'S
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, next) {
// Handle the get for this route
});
app.post('/', function(req, res, next) {
// Handle the post for this route
});
Related
I'm trying to do a post with a form on react, but when i submit for the name, the browser console always show "404 not found localhost:3000/store-data"
Sometimes it works, but in the database the value "name" is "NULL"
i dont know where is the error. so i need some help.
My db:
CREATE TABLE users(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(200)
)ENGINE=INNODB;
My Form.js code:
import React from 'react'
class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = { name: '' };
}
handleChange = (event) => {
this.setState({[event.target.name]: event.target.value});
}
handleSubmit = (event) => {
alert('A form was submitted: ' + this.state);
fetch('/store-data', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
// We convert the React state to JSON and send it as the POST body
body: JSON.stringify(this.state)
}).then(function(response) {
console.log(response)
return response.json();
});
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} name="name" onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
export default MyForm;
And my server.js code:
const express = require("express");
const bodyParser = require('body-parser');
const cors = require("cors");
const mysql = require('mysql');
const app = express();
app.use(cors());
// parse application/json
app.use(bodyParser.json());
//create database connection
const conn = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'conex'
});
//connect to database
conn.connect((err) => {
if (err) throw err;
console.log('Mysql Connected...');
});
//add new user
app.post('/store-data', (req, res) => {
let data = { name: req.body.name };
let sql = "INSERT INTO users SET ?";
let query = conn.query(sql, data, (err, results) => {
if (err) throw err;
res.send(JSON.stringify({ "status": 200, "error": null, "response": results }));
});
});
app.listen(3000, () => {
console.log("Server running successfully on 3000");
});
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");
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
next();
});
I'm trying to do simple form.
So I'm making a Web Application app using React. so I have created a login/register function to allow users to either signup or login to their account. I have used an express server to send http requests to MYSQL database, I also created two endpoints to either '/register' or '/login'. For my frontend I have connected the app to those endpoints using Axios to post users data into the database. my application only works when both server and client files are running on the same port, which could be disrupted when you refresh the page, however, the app would totally work if you don't refresh the page. so my question is that how can I get those http requests and post them into my database without having my frontend and backend running on the same port. Thx:)
Frontend:
import React, { useState } from "react";
import axios from 'axios';
function Login2() {
//Saving the values in the form variable
const [form, setForm] = useState({
username: '',
email: '',
password: '',
});
//mode determines whether the form should disply login or register
const [mode, setMode] = useState('login');
//message is used to disply any form of error to the user
const [message, setMessage] = useState('');
//it updates the users values in case a change has been made
//used a spread operator to update the form by targeting .name and .value
const handleChange = (e) => {
setForm({
...form,
[e.target.name]: e.target.value,
});
};
//it is used when the form is submitted, sends message to the backend to either login or register
//if successful/denied response is saved in message
const handleSubmit = (e) => {
e.preventDefault();
if (mode === 'login') {
axios.post('http://localhost:3000/login', form)
.then((response) => {
setMessage(response.data);
})
.catch((error) => {
setMessage(error.message);
});
} else {
axios.post('http://localhost:3000/register', form)
.then((response) => {
setMessage(response.data);
})
.catch((error) => {
setMessage(error.message);
});
}
};
return (
<div className="App">
<form onSubmit={handleSubmit}>
<input
type="text"
name="username"
placeholder="Username"
value={form.username}
onChange={handleChange}
/>
{mode === 'register' && (
<input
type="email"
name="email"
placeholder="Email"
value={form.email}
onChange={handleChange}
/>
)}
<input
type="password"
name="password"
placeholder="Password"
value={form.password}
onChange={handleChange}
/>
<button type="submit">
{mode === 'login' ? 'Login' : 'Register'}
</button>
<button type="button" onClick={() => setMode(mode === 'login' ? 'register' : 'login')}>
Switch to {mode === 'login' ? 'Register' : 'Login'}
</button>
</form>
{message && <p>{message}</p>}
</div>
);
};
export default Login2;
Backend:
const express = require('express');
const app = express();
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: "??",
user: "??",
password: "??",
database: "??",
});
app.use(express.json());
app.post('/register', (req, res) => {
const { username, email, password } = req.body;
const reg = `INSERT INTO userTable (username, email, password) VALUES (?,?,?)`;
connection.query(reg, [username, email, password], (error) => {
if (error) throw error;
res.send('User registered successfully');
});
});
app.post('/login', (req, res) => {
const { username, password } = req.body;
const log = `SELECT * FROM userTable WHERE username = ? AND password = ?`;
connection.query(log, [username, password], (error, results) => {
if (error) throw error;
if (!results.length) {
return res.send('Username or password is incorrect');
}
res.send('Login successful');
});
});
app.listen(4000, () => {
console.log('Server listening on port 4000');
});
You are making post request to a wrong port. Your server is running on 4000 and your are making axios post request on port 3000. Do the following changes in your react code:
axios.post('http://localhost:4000/login', form)
and
axios.post('http://localhost:4000/register', form)
But since you are requesting to the server from a different port, other than on what its running (here in your project its 4000) you will get a CORS error. For that you need to install cors package and do the necessary configuration depending on your project.
Hope it helps.
Here is my App.js file (client side) :
import "./App.css";
import { useState } from "react";
import Axios from "axios";
function App() {
const [usernameReg, setUsernameReg] = useState("")
const [passwordReg, setPasswordReg] = useState("")
const register = () => {
Axios.post("https://localhost3001/register", {
username: usernameReg,
password:passwordReg,
}).then((response) => {
console.log(response);
});
};
return (
<div className="App">
<div className="information">
<h1>Register</h1>
<label>Name:</label>
<input
type="text"
onChange={(e) => {
setUsernameReg(e.target.value);
}}
/>
<label>Password:</label>
<input
type="text"
onChange={(e) => {
setPasswordReg(e.target.value);
}}
/>
<button onClick={register}>Register</button>
</div>
<div className="login">
<h1>Login</h1>
<label>Name:</label>
<input
type="text"
/>
<label>Password:</label>
<input
type="text"
/>
<button>Login</button>
</div>
</div>
);
}
export default App;
and this is my index.js file (server side) :
const app = express();
const mysql = require("mysql");
const cors = require("cors");
app.use(cors());
app.use(express.json());
const db = mysql.createConnection({
user: "x",
host: "here is my db IP",
password: "x",
database: "x",
});
db.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
app.post("/register", (req, res) => {
const username = req.body.username;
const password = req.body.password;
db.query(
"INSERT INTO test (username, password) VALUES (?,?)",
[username, password],
(err, result) => {
console.log(err);
}
);
});
app.listen(3001, () => {
console.log("Yey, your server is running on port 3001");
});
When I start my React app, no problem into the console, same when I start my index.js (console prints "Yey, your server is running on port 3001" and "Connected!" so there is no problem with the db connection).
But when I press the register button, there is no data sent to my DB and I have these messages in the Chrome DevTools :
POST https://localhost3001/register net::ERR_CONNECTION_TIMED_OUT
and
Uncaught (in promise) Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:84)
I have also in these DevTool (network window) :
Failed to load response data
What can I do to fix that please ?
You should change this line:
Axios.post("https://localhost3001/register", {
to this other
Axios.post("https://localhost:3001/register", {
You are missing a : to separate the url part (localhost) from the port 3001
use http://localhost:3001/register. Not https://localhost3001/register
From time to time we will make such silly mistakes :vvvv
I am creating a publishing application that needs to use communication between React and MySQL database to send information back and forth. Using Express as my JS server. The server code looks as follows:
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const cors = require('cors');
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'ArticleDatabase',
port: 3300,
socketPath: '/Applications/XAMPP/xamppfiles/var/mysql/mysql.sock'
});
// Initialize the app
const app = express();
app.use(cors());
appl.post('/articletest', function(req, res) {
var art = req.body;
var query = connection.query("INSERT INTO articles SET ?", art,
function(err, res) {
})
})
// https://expressjs.com/en/guide/routing.html
app.get('/comments', function (req, res) {
// connection.connect();
connection.query('SELECT * FROM articles', function (error, results,
fields) {
if (error) throw error;
else {
return res.json({
data: results
})
};
});
// connection.end();
});
// Start the server
app.listen(3300, () => {
console.log('Listening on port 3300');
});
And my React class looks as follows:
class Profile extends React.Component {
constructor(props) {
super(props);
this.state = {
title: '',
author: '',
text: ''
}
}
handleSubmit() {
// On submit of the form, send a POST request with the data to the
// server.
fetch('http://localhost:3300/articletest', {
body: JSON.stringify(this.state),
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'content-type': 'application/json'
},
method: 'POST',
mode: 'cors',
redirect: 'follow',
referrer: 'no-referrer',
})
.then(function (response) {
console.log(response);
if (response.status === 200) {
alert('Saved');
} else {
alert('Issues saving');
}
});
}
render() {
return (
<div>
<form onSubmit={() => this.handleSubmit()}>
<input type = "text" placeholder="title" onChange={e =>
this.setState({ title: e.target.value} )} />
<input type="text" placeholder="author" onChange={e =>
this.setState({ author: e.target.value} )} />
<textarea type="text" placeholder="text" onChange={e =>
this.setState({ text: e.target.value} )} />
<input type="Submit" />
</form>
</div>
);
}
}
So fairly standard stuff that I found in online tutorials. I can search my database and display fetched info no problem, but not the other way around. When I try to take input from the <form> tag nothing is inserted into my database but instead I get this error:
[Error] Fetch API cannot load
http://localhost:3000/static/js/0.chunk.js due to access control
checks.
Error: The error you provided does not contain a stack trace.
Unhandled Promise Rejection: TypeError: cancelled
I understand that this has something to do with access control but since I am already using cors and can successfully retrieve data from the database, I am not sure what I am doing wrong. Any suggestions will be greatly appreciated. Thank you in advance.
You'll need to isolate the problem by first verifying that your service point is CORS Enabled. In order to focus solely on CORS functionality, I would remove the MySQL code temporarily.
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
app.use(cors());
app.get('/', function(req, res){
var root = {};
root.status = 'success';
root.method = 'index';
var json = JSON.stringify(root);
res.send(json);
});
app.post('/cors', function(req, res) {
var root = {};
root.status = 'success';
root.method = 'cors';
var json = JSON.stringify(root);
res.send(json);
})
// Start the server
app.listen(3300, () => {
console.log('Listening on port 3300');
});
One you have server listening on port 3300, run the following PREFLIGHT command at the terminal.
curl -v \
-H "Origin: https://example.com" \
-H "Access-Control-Request-Headers: X-Custom-Header" \
-H "Acess-Control-Request-Method: POST" \
-X OPTIONS \
http://localhost:3300
If the preflight request is successful, the response should include Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers
Now run the POST method.
curl -v \
-H "Origin: https://example.com" \
-H "X-Custom-Header: value" \
-X POST \
http://localhost:3300/cors
If the post request is successful, the response should include
Access-Control-Allow-Origin
If everything looks good, your server is okay. You then need to try the post method from your iOS app.
NOTE. I would also be suspicious of using cors on localhost. I would map 127.0.0.1 to a domain and then have the app use that domain instead. If you are on Linux or Mac, you modify /etc/hosts. For Windows it's c:\windows\system32\drivers\etc\hosts
Try explicitly whitelisting the server that is making the request:
const whitelist = ['http://localhost:3000']; // React app
const corsInstance = cors({
origin: (origin, callback) => {
if (!origin || whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
});
application.use(corsInstance);
https://expressjs.com/en/resources/middleware/cors.html#configuring-cors-w-dynamic-origin
You need to add event.preventDefault() at the end of your handleSubmit method (check this example https://stackblitz.com/edit/react-forms).
You have to do it for the reason for preventing form default behavior on submit: it tries to synchronously send data to the url it loaded from (since there is no action attribute on it).
For those who may have run into a similar problem, I was able to fix it by dumping express server altogether. I simply used the .php file on the Apache server to insert data into database. Hope it helps somebody.
I got this simple code from a tutorial to a sample login html form to detect if user and the password are on my database for a user register or not.
this code can detect the email if exist but not the password.
what's wrong in here?
var express = require('express');
var app = express();
var server = require('http').createServer(app);
bodyParser = require('body-parser');
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
database: 'chmult',
user: 'root',
password: '',
});
users = [];
connections = [];
app.get('/', function(req, res){
res.sendFile(__dirname + '/');
});
app.use(bodyParser.urlencoded({
extended: true
}));
/**bodyParser.json(options)
* Parses the text as JSON and exposes the resulting object on req.body.
*/
app.use(bodyParser.json());
connection.connect();
app.post('/', function(req, res){
var username= req.body.user.username;
var password = req.body.user.password;
connection.query('SELECT * FROM tesko WHERE username = ?',[username], function (error, results, fields) {
if (error) {
// console.log("error ocurred",error);
res.send({
"code":400,
"failed":"error ocurred"
})
}else{
// console.log('The solution is: ', results);
if(results.length >0){
if([0].password == password){
res.send({
"code":200,
"success":"login sucessfull"
});
}
else{
res.send({
"code":204,
"success":"Email and password does not match"
});
}
}
else{
res.send({
"code":204,
"success":"Email does not exits"
});
}
}
});
});
app.listen(3231);
console.log('Example app listening at port:3231');
my html forms
<form method="post" action="">
<input type="text" name="user[username]">
<input type="text" name="user[password]">
<input type="submit" value="Submit">
</form>
</html>
The column names on my table are (username,password). Both are varchar and I tried with other table that have md5. Still can't detect the password.
this bit of code looks suspicious:
if(results.length >0){
if([0].password == password){
res.send({
"code":200,
"success":"login sucessfull"
});
}
particularly [0].password I'd expect that to be undefined.
[0] is an array literal here, instead of an index into an array. You probably want results[0].password instead, judging by the line before it.