I'm sending the file to the backend (written in Express JS) using fetch API with FormData API. My application is working fine. But after clicking on the Send button, my page is getting refreshed, even though I have not used any HTML form element.
I deleted FormData inside of Send button event listener function callback, and page didn't refresh after that. I also deleted fetch api call but keeping the FormData, and then also page didn't refresh. But on using them together, page gets refreshed.
Front End Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Code Analyzer</title>
</head>
<body>
<h1>Insert the Code File here</h1>
<input type="file" name="myFile" />
<button class="btn">Send</button>
</body>
<script>
//Get the DOM elments
const btn = document.querySelector(".btn");
let input = document.querySelector('input[type="file"]');
let formData = new FormData();
btn.addEventListener("click", e => {
e.preventDefault();
formData.append("myFile", input.files[0]);
console.log(formData);
fetch("http://localhost:9000/analyze", {
method: "POST",
body: formData
})
.then(data => data.json())
.then(res => console.log(res))
.catch(err => console.log(err));
});
</script>
</html>
Back End Code:
//Importing Packages
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const multer = require("multer");
const app = express();
//Configuring Multer
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, "uploads");
},
filename: function(req, file, cb) {
cb(null, file.fieldname + "-" + Date.now());
}
});
const upload = multer({ storage: storage });
//Middlewares
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
//Routes
app.post("/analyze", upload.single("myFile"), (req, res) => {
console.log(req.file);
res.json({ Analyzed: "Yes" });
});
//Server Listening
app.listen(9000, () => {
console.log("Server started on 9000");
});
I had the same problem using create-react-app and I execute serve -s build after create a production repo, when I tried see the problem it's gone. I figure out that is in developer mode that it's happen.
Related
I have a node.js project where I need to pass data from js file to html file
js file code
const express = require('express');
const router = express.Router();
const path = require('path');
const db = require('Dal/ProductsDal');
const productsArray = db.showAll();
router.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '/home.html') , {obj: productsArray })
})
module.exports = router;
html file code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Node.Js Concluding Exercise</title>
</head>
<body>
<h1>Welcome</h1>
<div>
products
</div>
</body>
</html>
How can I show the product array in html div?
You could read the html file from node with a file reader and look for the div tag and replace with the data.
example code below
const http = require('http');
const fs = require('fs');
http.createServer(function (req, res) {
fs.readFile('index.html', 'utf-8', function (err, data) {
res.writeHead(200, { 'Content-Type': 'text/html' });
const products = 'some data';
const result = data.toString('utf8').replace('<div>products</div>', products);
res.write(result);
res.end();
});
}).listen(3000);
Using template engines with Express
A template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page.
https://expressjs.com/en/guide/using-template-engines.html
When pressing the button which sends a POST request, the request is fired twice but only after the page is freshly reloaded. The code's function is when the button is pressed, it sends a POST request to the url which then adds 1 to the JSON data value.
This is the button code in script:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<button id="button">Click Me</button>
</body>
<script>
$("#button").click(function () {
$.ajax({
type: "POST",
url: "/updating",
});
});
</script>
</html>
This is the nodejs/url code:
const express = require("express");
const app = express();
const path = require("path");
const fs = require("fs");
const PORT = 1000;
// Sets public as static dir
app.use("/", express.static(path.join(__dirname, "/public")));
const filepath = "public/data.json"
const rawdata = fs.readFileSync(filepath);
// Addin 1 to JSON value
app.post("/updating", (req, res) => {
var data = JSON.parse(rawdata);
data.data++;
var newdata = JSON.stringify({
data: data.data,
});
fs.writeFileSync(filepath, newdata);
});
app.listen(PORT, () =>
console.log(`Server started on port ${PORT}: http://localhost:${PORT}/`)
);
});
JSON file:
{"data":29}
EDIT: The problem is due to nodemon. This error only occurs when I'm running on dev dependency which only includes nodemon.
I have been doing some research on dynamically changing the meta tags for my react Js application. I have tried so many solutions such as Helmet but I have not succeeded.
I will be glad if someone can give me a clear algorithm on this task. I have two backends one is in Express and another one in PHP. I created the Express backend purposely for this task yet I have not succeeded in getting the meta tags change when I share my link to other platforms like Facebook.
My current implementation.
Frontend:
My Index.html inside public has
<title>$OG_TITLE</title>
<meta name="description" content="$OG_DESCRIPTION" />
<meta property="og:title" content="$OG_TITLE" />
<meta property="og:description" content="$OG_DESCRIPTION" />
<meta property="og:image" content="$OG_IMAGE" />
Express Backend
const express = require('express');
const cors = require("cors");
const path = require('path');
const fs = require('fs');
const app = express();
app.use(cors());
const port = process.env.PORT || 2800;
app.use('/api/dynamicmeta', (req, response)=>{
const filePath = path.resolve(__dirname, './build', 'index.html')
fs.readFile(filePath, 'utf8', function (err,data) {
if (err) {
return console.log(err);
}
data = data.replace(/\$OG_TITLE/g, 'Contact Page');
data = data.replace(/\$OG_DESCRIPTION/g, "Contact page description");
result = data.replace(/\$OG_IMAGE/g, 'https://i.imgur.com/V7irMl8.png');
response.send(data);
});
});
app.use(express.static(path.resolve(__dirname, './build')));
app.get('*', function(request, response) {
const filePath = path.resolve(__dirname, './build', 'index.html');
response.sendFile(filePath);
});
app.listen(port, () => console.log(`listening on port ${port}!..`));
module.exports = {
app
}
At this point, I am confused on how to continue because the title of my build doesn't change.
I have been trying to develop an web-app but remains stuck on the login. When I test the program on the localhost the login function works perfectly and navigate to the page that I expected. The main issue occurs after the deployment with firebase web hosting. When I deploy the web with firebase web hosting and test it, the login navigates back to the login page without any errors being displayed.
Note that I have already done the following:
set up the support email
Use the domain xxx.firebaseapp.com
enable the authentication option for email/password as "enabled"
Backend - node.js
Frontend- plain html and css
The system login is implemented as follow:
login.js
let loginForm = document.getElementById("login");
loginForm.addEventListener("submit", (event) => {
event.preventDefault();
var token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const login = event.target.username.value;
const password = event.target.password.value;
firebase
.auth()
.signInWithEmailAndPassword(login, password)
.then(({ user }) => {
return user.getIdToken().then((idToken) => {
return fetch("/sessionLogin", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"CSRF-Token": token,
},
body: JSON.stringify({ idToken }),
});
});
})
.then(() => {
return firebase.auth().signOut();
})
.then(() => {
window.location.assign("/");
})
.catch((error) => {
alert(error.message);
});
return false;
});
login.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Geographic Research - Login</title>
<meta name="csrf-token" content="{{csrfToken}}">
<link rel="stylesheet" href="/css/login.css">
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-app.js" defer ></script>
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-auth.js" defer ></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie#rc/dist/js.cookie.min.js" defer ></script>
</head>
<body>
<main>
<section>
<form id="login">
<center> <h1> Login </h1> </center>
<div class="col">
<input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" minlength="8" placeholder="Password" required>
<input type="submit" value="Login">
<button onclick= "window.location.href='/signup';" class="signup btn"> Sign Up </button>
</div>
</form>
</section>
<script defer src="/js/firebase_init.js"></script>
<script defer src="/js/login.js"></script>
</main>
</body>
</html>
index.js
// List of dependencies used in the code
const functions = require('firebase-functions');
const cookieParser = require('cookie-parser');
const csrf = require('csurf');
const bodyParser = require("body-parser");
// The Firebase Admin SDK to access Cloud Firestore.
const admin = require('firebase-admin');
const express = require('express');
const cors = require('cors');
// Module handling on csv file and file system
const csv = require('csv-parser');
const fs = require('fs');
// Module working on file uploads
const formidable = require("formidable");
var hbs = require('handlebars');
var engines = require('consolidate');
const path = require('path');
// Initialize firebase application
var serviceAccount = require('./service_account.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://sadao-f4a1e.firebaseio.com"
});
const app = express();
const csrfMiddleware = csrf({cookie: true});
app.engine('hbs', engines.handlebars);
app.set('views', path.join(__dirname, "views/"));
app.set('view engine', 'hbs');
app.use(cors({ origin: true }));
app.use(express.static(path.join(__dirname, '/public')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(csrfMiddleware);
app.all("*", (req, res, next) => {
res.cookie("XSRF-TOKEN", req.csrfToken());
res.locals._csrf = req.csrfToken();
next();
})
const db = admin.database();
// API handling Authentication , Login, Logout
app.get('/login', async(req, res) => {
res.render('login', {csrfToken: req.csrfToken()});
});
app.get('/signup', async(req, res) => {
res.render('registration');
});
app.post("/sessionLogin", (req, res) => {
const idToken = req.body.idToken.toString();
const expiresIn = 60 * 60 * 24 * 5 * 1000;
admin.auth().createSessionCookie(idToken, {expiresIn}).then(
(sessionCookie) => {
const options = { maxAge: expiresIn, httpOnly: true};
res.cookie("session", sessionCookie, options);
res.end(JSON.stringify({status:"success"}));
},
(error) => {
res.status(401).send("UNAUTHORISED REQUEST");
}
);
});
I really need help on this! Can anybody please help me out ;(
Two things you could try here:
Do not use form to submit your password, simply use input. Firebase submits the password and email by themselves with the functions.
In your Firebase console, under the authentication => sign-in method section, if you scroll below, make sure that you have the authorized domains of the domain where you are deploying your app enabled.
I want to render some value of another website by fetching the HTML source data by REST request, console the value inside the span tag to my console log and render it to my HTML.
I can't managed to this by my current code, he receives the data before the DOM is ready and the specific san tag i need still not there.
My current code -
async function uiTagChecking() {
let url ='http://production.com:8000/loginPage#';
fetch(url)
.then(await sleep(6000))
.then(response => response.text())
.then(pageSource => console.log(pageSource));
}
The current source code I've fetched (this is before the DOM is ready and the needed span tag doesn't there yet)
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>loading...</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="icon"
type="image/png"
href="images/favicon.png?v=9">
<!--<link href="assets/vendors/keylines/map/leaflet.css" rel="stylesheet">-->
<link href="XXXX" rel="stylesheet"></head>
<body>
<div id="app"></div>
<script src="assets/vendors/jquery.min.js"></script>
<script type="text/javascript" src="XXXX/index-c08574aac712ae81e016.js"></script></body>
</html>
The span tag i want to print and render -
<span class="version-for-qa">2.1.1</span>
But it appears only after the redirect is ended and the DOM is ready.
Technical info:
Node JS
JavaScript
HTML + CSS
My server file (express):
var express = require('express');
var cors = require('cors');
var app = express();
var path = require("path");
var fetch = require('fetch-cookie')(require('node-fetch'));
var btoa = require('btoa');
var http = require('http');
var fs = require('fs');
var corsOptionsDelegate = function (req, callback) {
var corsOptions;
if (whitelist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
}else{
corsOptions = { origin: false } // disable CORS for this request
}
callback(null, data , corsOptions) // callback expects two parameters: error and options
};
app.engine('.html', require('ejs').__express);
app.set('views', __dirname + '/view');
app.set('view engine', 'html');
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res){
res.render('index');
res.render('logo');
res.writeHead(200, {'Content-Type': 'application/json'});
});
app.use(cors());
app.set(['$qProvider', function ($qProvider) {
$qProvider.errorOnUnhandledRejections(false);
}]);
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
});
app.listen(8033, function () {
console.log('CORS-enabled web server listening on port 8033')
});