This question already has answers here:
How can I download a file using window.fetch?
(10 answers)
Closed 9 months ago.
I am working in a fullstack project I have backend folder using nodejs with server.js file of the following code
const express = require("express");
const cors = require("cors");
const path = require("path");
const app = express();
app.use(express.static(path.join(__dirname, "puplic/uploads")));
app.use(cors());
app.get("/", async (req, res) => {
res.download("b.rar");
});
app.listen(3000, () => {
console.log("server connected");
console.log(path.join(__dirname, "puplic/uploads"));
});
and client side of index.html of the following 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>Document</title>
</head>
<body>
<button id="btn">press</button>
<script src="index.js">
</script>
</body>
</html>
and client side index.js of the following code
let btn=document.getElementById("btn")
btn.onclick=()=>{
fetch("http://localhost:3000/",{
method:"GET",
mode:"cors"
}).then(res=>
{
}
)
}
how i can fetch the server side and download the file in the client pc
when the client press the button
I would recomment to redirect to a blank page and set a download header there.
Client side would look like this:
let btn=document.getElementById("btn")
btn.onclick=()=>{
window.open("http://localhost:3000/", '_blank')
}
on the serverside you have to set a download header, code would look like this:
app.get("/", async (req, res) => {
res.download("b.rar");
});
optional you can set the headers by yourself using:
app.get("/", async(req, res) =>.{
res.set({
"Content-Disposition": "attachment; filename=\"b.rar\"",
"Content-Type": "application/x-rar-compressed, application/octet-stream"
});
const fs = require('fs/promise');
fs.readfile('./b.rar').then(file => {
res.send(file);
})
});
I havent tested this whole stuff but maybe it can help you. Optional it is enough to use an tag instead of a button and manage the redirection there since some browsers deny window.open from javascript due to cross site injection.
Related
This question already has answers here:
How to load javascript code to an html file at runtime?
(5 answers)
Closed 10 days ago.
My webpage creates a new script element and then loads the script from a localhost server. The problem is that the script cannot be loaded and shows PROTOCOL ERROR:
https://localhost:4200/script/test.js net::ERR_SSL_PROTOCOL_ERROR
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link href="./public/nps.style.css" rel="stylesheet" />
<script>
j = document.getElementsByTagName('script')[0],
k = document.createElement('script');
k.src = 'http://localhost:4200/script/test.js';
j.parentNode.insertBefore(k,j);
</script>
</head>
<body>
<p>Testing</p>
</body>
</html>
Then create a localhost server to listen it so the JavaScript file can be downloaded
index.js:
const express = require('express');
const cors = require('cors');
const { test } = require('./script/test.js');
const api = express();
api.use(cors({origin: '*'}));
api.use('/script', express.static('public'));
api.listen(4200, () => {
console.log("Server listening");
})
test.js:
alert("it works!");
How can I solve this issue?
Update:
Initially I had the source of the new script element as 'https://localhost:4200/script/test.js', So I changed to http, a new error occurred:
GET http://localhost:4200/script/test.js net::ERR_ABORTED 404 (Not Found)
Have you considered not using https? It looks like this could be your issue running locally.
The protocol error is the giveaway.
You just change 2 lines of your index.js code to solve it. Try with this code :
const express = require('express');
const cors = require('cors');
// const { test } = require('./script/test.js');
const api = express();
api.use(cors({ origin: '*' }));
api.use(express.static('public'));
api.use('/script', express.static('script'));
api.listen(4200, () => {
console.log("Server listening");
});
And make sure your directory/file management looks like this :
I have an app that I followed from a tutorial for the backend in nodeJS and Express. My connection to MongoDB via Mongoose is working. However, I've been trying to add a front-end- at the moment- just a simple html/ejs/css form. My endpoints are loading in localhost but only the html/ejs is rendering. My css file shows as plain code at http://localhost:3000/styles.css but isn't loading so I'm just getting plain html/ejs. I'm using VS Code. Here's my relevant code:
App.js:
const express = require('express');
const bodyParser = require('body-parser');
const product = require('./routes/product.routes'); // Imports routes for the products
const app = express();
var path = require('path');
const cors = require('cors');
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cors({
origin: '*'
}));
app.use(express.static(path.join(__dirname, '/public')));
app.use(express.static(path.join(__dirname, 'views')));
app.use("/styles", express.static(__dirname + '/styles'));
app.use('/product', product);
let port = 3000;
app.listen(port, () => {
console.log('Server is up and running on port number ' + port);
});
Product.routes.js
const express = require('express');
const router = express.Router();
// Require the controllers WHICH WE DID NOT CREATE YET!!
const product_controller = require('../controllers/product.controller');
// a simple test url to check that all of our files are communicating correctly.
router.get('/', product_controller.start);
router.get('/test', product_controller.test);
router.post('/create', product_controller.product_create);
router.get('/:book', product_controller.product_details);
router.put('/:book/update', product_controller.product_update);
router.delete('/:book/delete', product_controller.product_delete);
module.exports = router;
Product.controller.js
const Product = require('../models/product.model');
//Simple version, without validation or sanitation
exports.start = function (req, res) {
res.sendFile('index.html', { root: './views' })}
exports.test = function (req, res) {
res.render('index.ejs', { root: './views' })}
Index.ejs
<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>HTML 5 Boilerplate</title>
<link rel="stylesheet" type="text/css" href='/public/styles.css'/>
<base href="/">
</head>
<body>
<h1>BookBooker</h1>
<h2>A library app for personal use.</h2>
<form action="/create" method="POST">
<input type="text" placeholder="Writer" name="name" />
<input type="text" placeholder="Book" name="book" />
<button type="submit">Submit</button>
</form>
<script src="app.js" type="module" type='text/javascript'></script>
</body>
</html>
My file structure looks like:
CRUD folder
-app.js
-package.json
-package-lock.json
-controller folder
--product.controller.js
-public folder
--styles.css
-routes folder
--product.routes.js
-views folder
--index.html
--index.ejs
Apologies if it's obvious- I'm super new to this. As you can see, I've tried static files, paths, CORS, and lots of combinations of file routing but I'm getting myself in a big muddle. I've considered caching but the css isn't showing in Chrome, Edge or Incognito mode either. Any help would be appreciated.
Instead of
<link rel="stylesheet" type="text/css" href='/public/styles.css'/>
write
<link rel="stylesheet" type="text/css" href='/styles.css'/>
The public folder name is not part of the stylesheet URL, it is just the folder where express.static looks for files.
The CSS showing as plain text may be caused by a wrong Content-type in the header. The browser is interpreting it as a plain text file, instead of handling it as CSS. Before you send the response, you can set response headers in your controller like:
res.header('Content-type', 'text/css');
See Express Docs
Hope this helps.
I create a server using nodejs with express
server.js
const express = require('express');
const app = express();
const path = require('path');
const router = express.Router();
router.get('/',function(req,res){
res.sendFile(path.join(__dirname+'/index.html'));
//__dirname : It will resolve to your project folder.
});
//----------------------------------------------------------------------
//add the router
app.use(express.static(__dirname + '/View'));
//Store all HTML files in view folder.
app.use(express.static(__dirname + '/Script'));
//Store all JS and CSS in Scripts folder.
app.use('/', router);
app.listen(process.env.port || 3000);
And use html with javascript.
index.html
<html>
<head>
<meta charset="utf-8"/>
</head>
<link rel="stylesheet" href="./index.css">
<script type="text" src="./server.js"></script>
<script src="./index.js"></script>
<body>
<h1>Automatico</h1>
<button onclick="autohabilitar();">Habilitar</button>
<button onclick="autodeshabilitar();">deshabilitar</button>
<br>
<h1>Foco-1</h1>
<button onclick="f1habilitar();" id="f1h">Habilitar</button>
<button onclick="f1deshabilitar();"id="f1d">deshabilitar</button>
</body>
</html>
index.js
document.getElementById("f1h").disabled=true;
document.getElementById("f1d").disabled=true;
}
function autodeshabilitar(){
document.getElementById("f1h").disabled=false;
document.getElementById("f1d").disabled=false;
}
function f1habilitar(){
document.getElementById("f1h").disabled=true;
document.getElementById("f1d").disabled=false;
}
function f1deshabilitar(){
document.getElementById("f1d").disabled=true;
document.getElementById("f1h").disabled=false;
}
I need the function
function apagarf1(){
led1.off();
}
located in server.js for use in onclick of the button...
I tried export the function, import the script in the html, use johnny-five in another script...
I’m not super familiar with Johnny 5. But I do know you can’t access node.js specific stuff from the browser.
Your best bet will be to set up a basic api endpoint in express that you call from your front end code. When that endpoint gets hit you can trigger your nodejs function to turn the led off.
In your server file add this:
app.get('/led-off', (req, res) => {
apagarf1()
return res.send('LED off');
});
On your front end make a fetch() call to that endpoint and that should work.
I have a node server running with express which listens to incoming requests. I am rendering an HTML file which I would like to update when I receive a GET request in my server. However, the data that is sent to my server is sent by an API when an external event happen (asynchronously). I don't know how to update the HTML file I'm serving with the JSON content of the incoming request. Particularly, I am trying to replace the inner.HTML content of the incoming class as you can see in my code.
I have tried to use the fetch API on the client side to make a request to the server to retrieve this data, but it doesn't seem to work.
Server.js
const bodyParser = require('body-parser');
const port = 3000;
const app = express();
const server = app.listen(port, () => console.log('App listening on port ${port}'));
app.set('view engine', 'html');
app.engine('html', ejs.renderFile);
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended:true}));
app.get (‘/incoming', (req,res)=>{
const { status} = req.url;
res.json(status);
console.log(status);
}) ```
Client.js
fetch('http://localhost:3000/incoming').then(function(response) {
return response.json();
}).then(response => {
document.getElementById("dlr").innerHTML = response
}).catch(error => console.error(error))
index.html
<!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">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/css-layout/1.1.1/css-layout.js" />
<title>Node SMS Texting</title>
</head>
<body>
<div class="container">
<h2>Text API</h2>
<input type="sender" name="from" id="from" placeholder="Enter sender ID ...">
<input type="button" id="button" value="Send Text" class="button button-primary">
<p class="response"></p>
<p class="incoming"></p>
</div>
<script src="js/client.js"></script>
</body>
</html>
I get the result logged in the console as per my console.log in the server side, but the client doesn't receive anything. This is the console.log
/incoming?user=A&to=Me&code=21404&Id=150000001A01F77B&×tamp=2019-04-08+15%3A57%3A15×tamp=1554739095&nonce=59167e2f-654c-4dd5-b236-bff9ac97f917
The only thing I see happening on the client side is /incoming set as text set under the incoming.innerhtml class, but not the content of the GET request sent to my server.
Any help here would be highly appreciated.
Thanks in advance.
Regards,
Javier
You are sending a GET request to a POST endpoint. This you can fix by passing a body and a method in your fetch on client side. Also, you should handle the response as it comes back. Rewrite your fetch to something like this.
fetch('http://localhost:3000/incoming', {
method: 'post',
body: JSON.stringify(body)
}).then(response => {
document.getElementById("incoming").innerHTML = response
}).catch(error => console.error(error))
having trouble getting this to run with node
const express = require('express')
const app = express()
app.use(express.static('public')) //adds content of public folder
app.get('/', function (req, res){
res.sendFile('/views/index.html', {root: __dirname})
})
app.listen(1337, function (){
console.log('lab5-server.js listening on 1337')
})
it was running perfect yesterday and now it's not. There's also an issue with the .html portion, it wont display the image I have assigned. Quick note it that I left out most of whats written below the source code for the image, it's not necessary for this question.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1> <center> Welcome to Matt's Page </center></h1>
<center> <img src = "images/AlgorithmofSuccess.jpg"/> </center>
Does anyone see where I went wrong and why the terminal is returning "unexpected token" on the javascript portion?
You should try to use the path module to help point to your public path. I can give you an example:
const path = require("path");
const app = express();
const publicPath = path.resolve(__dirname, "./public");
// We point to our static assets
app.use(express.static(path.resolve(__dirname, "./public")));
app.get("/*", (req, res) => {
res.sendFile("index.html", { root: path.join(__dirname, "./public") });
});
// And run the server
app.listen(1337, () => {
console.log(`Server running on port ${port}`);
});
Make sure that ./public or ./dist path contains your index.html
I solved this, just had to change the folder of the lab5-server.js file i was using, thanks for the help guys