Is it possible to have a hidden Javascript file - javascript

If I were to serve the localhost root file a HTML file like so:
app.get('/', (req, res) => res.sendfile('index.html'))
Can I add Javascript files to the HTML document that can't be viewed or touched by the browser?
And if so, is it possible that it can also have access to node api's?
Im new to Express so I have no clue how it works.

You can have the server do some work after receiving parameters from the frontend.
The javascript loaded in the DOM will send a request to the server, the server will do some work, unknown to the frontend JS, then return the result.
On Server:
app.post('/path', (req, res) => {
const json = req.body;
//do work
const resp = {some: 'data'};
res.json(resp);
}
On Frontend
fetch('/path', {
method: 'post',
body: JSON.stringify(data),
headers: { 'Content-type': 'application/json' }
})
.then(res => res.json()) // get json data out of response object
.then(json = > {
// do something with response json
}
You'll want to do some reading on Express and body parsing, as well as using parameters in GET requests as opposed to body in POST requests, also other types of requests.

Related

GET request working through Postman but the browser tells me GET request cannot have body

I'm simply trying to send some urlencoded parameters via a GET request using fetch. I'm just trying to print the parameters using Express at the moment, like so:
app.get('/api', function (req, res) {
console.log(req.body);
res.sendStatus(200);
return;
});
This works just fine in Postman using a GET request and x-www-form-urlencoded key-value pairs. The webserver will print all the key-value pairs just fine.
But when I try and use fetch to do the exact same thing I get nothing but problems. I've tried two different methods:
fetch(`http://localhost:3000/api?user=test&password=123`, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
The request does go through using this method, but the webserver only prints {} - an empty object.
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("user", "test");
urlencoded.append("password", "123");
var requestOptions = {
method: 'GET',
headers: myHeaders,
body: urlencoded,
};
fetch("localhost:3000/api", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
The request does not go through using this method, and the browser gives me the error TypeError: Window.fetch: HEAD or GET Request cannot have a body.
This code was generated using the request that works in Postman using the generate code snippets option.
What am I doing wrong?
The parameters in this URL:
http://localhost:3000/api?user=test&password=123
are in the query string, not in the body and thus the content-type does not apply to them - they are properly encoded to be in a URL. In Express, you would access these with req.query. You should see a value for req.query.user and req.query.password in your Exprss request handler.
Note, it is not recommended that you send user credentials in a URL like this because URLs are often present in log files at your ISP, at the recipient server, in proxies, in your browser history, etc... User credentials like this should be sent in POST request over https where the credentials would go encoded in the body (where it won't be logged or saved by intermediaries).
The fetch error is accurate. GET requests do not have a body sent with them. That would be for POST or PUT requests. A GET request is a "get" request for a resource that you specify only with a URL.
You're confusing request body with a query string.
Your second request (you don't need a Content-Type for it)
fetch("http://localhost:3000/api?user=test&password=123");
would be handled by the following Express function:
app.get('/api', function (req, res) {
console.log(req.query); // Note that query, not body is used.
res.sendStatus(200);
return;
});
You can access fields from the query object as req.query.user && req.query.password.
As for having a request body in a GET request: while RFC doesn't explicitly fordbid it, it requires server to not change response based on the contents of the body, i.e. the body in GET has no meaning in the standard, so JS HTTP APIs (both fetch & XmlHttpRequest) deny it.
firstly if you are trying to get some data from your API or others API you should do GET request in order to get your desired data from server for example, if you want to get a specific things like a user or something else you can pass your data in GET request URL using query string or route params.
secondly, if you want to authenticate and send your credentials to the server its not recommended to use GET request as i said earlier GET request simply is for fetching some data from server, so if you want to send your credential or anything else you are better off using POST request to send data to the server and you can't do POST request in the browser, so you have to use something like postman or insomnia in order to send your POST request to the server. i hope it could help you to solve your issue.

why does expressjs generate ERR_EMPTY_RESPONSE for PUT when idle?

Currently
I have an express server that I am running locally to manage requests from a react client.
Problem
When my client is idle (I assume after the client PUT server actions previously), after about 3-5mins, error messages appear in the console logs.
Error Message:
This causes the next client PUT to the server to fail i.e. data is not saved.
Request
I don't have much experience with middleware management, so would appreciate some help on how to diagnose what may be causing this error.
Notes that may be helpful:
sometimes when the client makes too many PUTs to the server, the data fails to save, but there is no error message. I am forced to reload the page.
Extract from Client - App.js
saveData = data => {
console.log("Submitting request to save...");
fetch('/api/v1/savedata', {
method: 'PUT',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(console.log("Save complete!"));
};
Extract from Server.js:
// An api endpoint that saves data from the client
app.put('/api/v1/savedata', (req,res) => {
console.log('Server received request to saveData');
let options = {
files: './data/save.json',
changes: req.body
}
updateJsonFile(options);
});
you didn't sent any response in the API, use res.send or res.json like this:
app.put('/api/v1/savedata', (req,res) => {
console.log('Server received request to saveData');
let options = {
files: './data/save.json',
changes: req.body
}
updateJsonFile(options);
res.json({data: data}) // if you want to send json response
// Note: please don't send response object more than once
});

GET file (content and filename) with axios

There is an API endpoint which offers a downloadable file - when accessing the url directly from the browser - the file is saved automatically. However, I would like to target the given endpoint from my app, and fetch the file name and content to a reducer within my app's redux store.
I'm using axios for all API requests. In this case, I'm trying to do it like this:
axios({
url: API_ENDPOINT_URL,
method: "GET",
headers,
}).then((response) => {
// do some stuff
console.log("response ", response)
})
In this setup, response contains only data, there is no filename. How to go about this?
You can add a response type in axios that can be either stream or blob (depends on the file type)
axios({
method:'get',
url:'endpoint_url',
responseType:'stream'
})
.then(function (response) {
response.data.pipe(fs.createWriteStream('file_name.jpg'))
})
This is straight from axios documentation. Let me know if you need something else

Send data in post method to an api in node js

I want to send some post data to an api
10.11.12.13/new/request/create
this is an API to create a new request in portal. now I am making one application in NodeJs and want to create request from node js application.
now I have to send in this format
{"user":"demo", "last_name":"test","contact":"989898989"}
so how can I send data on above url to create a new request.
I am a beginner in NodeJs and don't have much idea.
any help will be appreciated.
Thanks in advance
I would recommend to use axios or any other request lib :
const axios = require('axios');
axios.post('10.11.12.13/new/request/create', {
user: 'demo',
last_name: 'test',
contact: '989898989',
});
here is an example using request module
var headers = {
'Content-Type': 'application/json'
}
var options = {
url: "10.11.12.13/new/request/create" ,
method: 'POST',
headers: headers,
json: true,
body: {user:"demo", last_name:"test",contact:"989898989"}
}
request(options, function (error, response, body) {
if (error) {
//do something
}
console.log(body)//do something with response
})
You can use postman REST client for GET method using your URL and Body (which you want to post) and click on * Code * and select NodeJS and their you will find code generated for you to work with. Here is the link https://www.getpostman.com/docs/postman/sending_api_requests/generate_code_snippets
With my experience, it is good to start with Request package for node js. Here is the link for your reference: https://www.npmjs.com/package/request

Request.post on already uploaded image file

I am using Angularjs and nodejs in the project and working on file uploads. I want to send the post request to the url endpoint in a secure way as I need to attach accesstoken with the request. So the way I did this was, I added the directive to choose the file from UI and once it gets the file, I append it using FormData() like this in the controller
var fd = new FormData();
fd.append('file',myFile);
and sending this formdata object to the nodejs server like mentioned here http://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
expect this request will be going to my nodejs server url from there I will be making another post request to external web service
$http.post('api/collections/upload',fd, {
transformRequest: angular.identity,
headers: {
'Content-type': undefined
}
});
So it will attach the right content-type and boundaries in the request. I am getting the file on server side nodejs when I do
function(req,res){
console.log(req.files); //I am able to see the file content
}
It is uploaded on the nodejs server side.
Now I want to make a post request using the req.files to a different endpoint along with proper accessToken and headers. Tried many things but not able to make the request go thru. Not sure how can I attach the imagedata/ req.files along with the request. I tried these two things mentioned in request npm module https://www.npmjs.org/package/request
1)
request.post({
url: 'https://www.example.com/uploadImage',
headers: {
'Authorization': <accessToken>,
'Content-type': 'multipart/form-data'
},
body: req.files
});
Don't know how can I attach and binary data with this request and how can I put boundary. Is boundary needed when you want to send the uploaded image with this request?
2)
fs.createReadStream(req.files.file.path, {encoding: base64}).pipe(request.post({
url: 'https://www.example.com/uploadImage',
headers: {
'Content-type': 'multipart/form-data'
}
}));
Can someone please suggest some ideas on how can I send this post request using request npm module? Thanks.
Documentation here has lots of examples of doing exactly what you describe:
https://github.com/mikeal/request#streaming
As can be seen in that link, the request library adds a .pipe() method to your http's req object, which you should be able to use like the examples in the link:
function(req, res) {
req.pipe(request.post('https://www.example.com/uploadImage');
}
Or something similar.
You were nearly there with your #2 try, but that would only work if you have previously written the file out to disk and were reading it in with fs.createReadStream()
your suggestion helped me to atleast know what I was trying was right. Another article that solved my problem was this http://aguacatelang.wordpress.com/2013/01/05/post-photo-from-node-js-to-facebook/ .Basically, here is what I did and it worked. Thanks for your suggestion.
var form = new FormData();
form.append('file', fs.createReadStream(__dirname + '/image.jpg'));
var options = {
url: 'https://www.example.com/uploadImage?access_token='+ <accesstoken>,
headers: form.getHeaders()
};
form.pipe(request.post(options,function(err,res){
if(err){
log.debug(err);
}
else {
log.debug(res);
}
}));

Categories

Resources