Cannot GET on POST request - javascript

I have an API that takes in 3 url parameters and writes into a mongodb collection. My understanding is that it should be post request since it's sending data to my back end, but when sending the data in, I get a Cannot Get... error.
routes.js
// JavaScript source code
var friends = require('./../controllers/friends.js');
module.exports = function(app)
{
app.post('/friends/new/:fname/:lname/:bday', function (request, response)
{
friends.create(request, response);
})
}
Controller:
// JavaScript source code
var mongoose = require('mongoose');
var Friend = mongoose.model('Friend');
module.exports =
{
create: function(request, response)
{
var friendInstance = new Friend();
friendInstance.first_name = request.params.fname;
friendInstance.last_name = request.params.lname;
friendInstance.b_day = request.params.bday;
friendInstance.save(function(err)
{
if (err)
{
response.josn(err);
}
}
URL:
http://localhost:8000/friends/new/Gelo/Maverick/9999-9-99
Error:
Cannot GET /friends/new/Gelo/Maverick/9999-9-99

You're seeing that error because you must be trying to access the url via the web browser, which sends the GET request. You should use an app like Postman to make POST requests instead.

Related

nodeJs basic authentication issue

I'm getting no proper response while make an API request to external API using basic authentication (username and password) in nodejs (javascript)
I used the below code and the response is "undefined", not sure what is missing here.
But I was able to make a request using postman tool without any issues.
const request = require('request')
const user = '*****';
const pass = '*****!';
const url = 'https://servicenow.com/api/table'
var options = {
url: url,
auth: {
username: user,
password: pass
}
};
request.get(options, (err, res, body) => {
if (err) {
return console.log(err);
}
console.log(body.url);
console.log(body.explanation);
});
Response:
undefined
undefined
if your api right with postman you can do like this based on photo
send a request
click on code
select nodejs- Request
copy

How to combine request coming from two different application take data from one request and send it as a response to the other request?

I am working on a project for my class. the application facilitate users to upgrade their PCs. The application has three parts a react front-end, node.js server and a C# application(scanner) that the user downloads from the from-end and runs it locally in user's PC. After the scanner is ran, it extracts the existing hardware specs from the user's PC and send it as a json object to the server through a HTTP request. the server API takes this information and generates a compatible upgraded parts list from our database. I am struggling to find a way to return this API generated data to the react front-end opened on the user's end.
The API is a REST API
I am new to using node js and dealing with HTTP requests. It will be helpful if some one can provide any solution, documentation or article which I could be helpful to implement this functionality. also feel free to give any suggestions on how to achieve this connection between the three parts.
Here is the code where react front end that is sending the request for scanner.exe
handleDownload = () =>{
const scn_URL = "http://localhost:5000/fileApi?name=User_scanner.exe";
Axios({
method: 'GET',
url: scn_URL,
responseType: 'blob'
})
.then(response =>{
console.log(response.data);
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'scanner.exe');
document.body.appendChild(link);
link.click();
})
}
here is the server side API code that is serving the scanner.exe file
var express = require("express");
var router = express.Router();
router.get("/", function (req, res, next) {
const fileName = req.query.name;
const filepath = "C:\\Users\\Sakib_PC\\my files\\senior_Design\\Senior_DesignS19_group_5\\back-end-testing\\serverAPI\\public\\User_scanner.exe"
console.log(`Got file name: ${fileName}`);
res.set({'Content-Type':'application/octet-stream'})
res.sendFile(filepath, function (err) {
if (err) {
next(err)
} else {
console.log('Sent:', fileName)
}
});
});
module.exports = router;
The scanner is sending the information as json to the server and named "data" in the code below
private async void SendJson_Click(object sender, EventArgs e)
{
Console.WriteLine("send button was clicked");
const string url = "http://localhost:5000/testApi";
var data = new StringContent(this.jsonData, Encoding.UTF8, "application/json");
string response;
HttpClient client = new HttpClient();
HttpResponseMessage res = await client.PostAsync(url, data);
response = res.Content.ReadAsStringAsync().Result;
Console.WriteLine(response);
if (response == "message recieved")
{
Console.WriteLine(response);
this.finishButton.Enabled = true;
}
else
{
Console.WriteLine("nothing ");
}
}
the code for API that catches this data is given below:
var express = require("express");
var router = express.Router();
router.post("/", function (req, res, next) {
const msg = req.body;
console.log(msg);
const modMsg = "message recieved";
res.send( modMsg);
})
module.exports = router;
the data that is being received by the server from scanner is given in the link which is what is intended.
image of the json data being send by the scanner
is there any way I can send the scanner data the api caught to the front end that made the download request in the first hand. Keeping in mind that the download GET request made from the website and POST request made from the scanner are two different request. My goal is to take the data from the scanner POST request and serve it to the client from where It made the Download request
thank you!

'Cannot set headers after they are sent to the client' error received after attempted to serve new html file

I'm very new to NodeJS, and I'm trying to follow/build off of a sample project built with the Spotify API and Express. The user is prompted to authenticate on the home page, and then I want to have them land at a different html file where relevant information will be displayed from the API. To my understanding "app.get" specifies what should happen once that endpoint is navigated to, so I thought that when my client.js file gets '/nextfile', I would present it with a new html file for that endpoint with response.sendFile(__dirname + '/views/nextpage.html'); within app.get('/nextpage').
Obviously, this isn't correct, because when I run the server, it simply returns to the index.html file after authentication, with an error that reads:
UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
I tried looking into this error, but I couldn't find anything that helped me solve my specific problem. Relevant excerpts from my client.js and server.js files are below:
Server.js
/** when home page is requested, respond with this file **/
app.get("/", function (request, response) {
response.sendFile(__dirname + '/views/index.html');
});
//-------------------------------------------------------------//
// init Spotify API wrapper
var SpotifyWebApi = require('spotify-web-api-node');
// Replace with your redirect URI, required scopes, and show_dialog preference
var redirectUri = 'http://localhost:8888/callback',
clID = '9013dc5d86b84ffca62df2f22e00968e',
clSEC = 'b9484118ab374707925b1b15100cc58b';
var scopes = ['user-top-read','streaming','user-read-private'];
var showDialog = true;
// The API object we'll use to interact with the API
var spotifyApi = new SpotifyWebApi({
clientId : clID,
clientSecret : clSEC,
redirectUri : redirectUri
});
app.get("/authorize", function (request, response) {
var authorizeURL = spotifyApi.createAuthorizeURL(scopes, null, showDialog);
console.log(authorizeURL)
response.send(authorizeURL);
});
// Exchange Authorization Code for an Access Token
app.get("/callback", function (request, response) {
var authorizationCode = request.query.code;
spotifyApi.authorizationCodeGrant(authorizationCode)
.then(function(data) {
console.log(data)
response.redirect(`/#access_token=${data.body['access_token']}&refresh_token=${data.body['refresh_token']}`)
}, function(err) {
console.log('Something went wrong when retrieving the access token!', err.message);
});
});
app.get("/logout", function (request, response) {
response.redirect('/');
});
app.get('/nextpage', function (request, response) {
**/* I want to serve his html file after the user is authenticated */**
response.sendFile(__dirname + '/views/nextpage.html');
var loggedInSpotifyApi = new SpotifyWebApi();
console.log(request.headers['authorization'].split(' ')[1]);
loggedInSpotifyApi.setAccessToken(request.headers['authorization'].split(' ')[1]);
// do stuff with the api
});
Client.js
$(function() {
$('#login').click(function() {
// Call the authorize endpoint, which will return an authorize URL, then redirect to that URL
$.get('/authorize', function(data) {
console.log(data)
window.location = data;
});
});
const hash = window.location.hash
.substring(1)
.split('&')
.reduce(function (initial, item) {
if (item) {
var parts = item.split('=');
initial[parts[0]] = decodeURIComponent(parts[1]);
}
return initial;
}, {});
window.location.hash = '';
if (hash.access_token) {
$.get({url: '/nextpage', headers: {"Authorization": `Bearer ${hash.access_token}`}}, function(data) {
// "Data" is the array of track objects we get from the API. See server.js for the function that returns it.
console.log(data)
var title = $('<h3>Your top tracks on Spotify:</h3>');
title.prependTo('#data-container-mod');
// For each of the tracks, create an element
data.items.forEach(function(track) {
var trackDiv = $('<li class="track"></li>');
trackDiv.text(track.name);
trackDiv.appendTo('#data-container ol');
});
});
}
});
Any help would be greatly appreciated.
The flow of your app in sending http headers appears to be like this from when the 'callback' url is reached at:-
A http header is sent alongside the redirect URL that contains the access token and refresh token.
Client.js takes the access token and sends it back through the /nextpage route with headers containing the access token
Send nextpage.html back to client.js and update the page accordingly..
What happens next?
Beware the browser tab still is on the route with the access tokens and refresh tokens.
So the jquery ajax request to '/nextpage' runs while the previous http headers had been sent already.
I however do not understand how the index.html is being returned..
can you try removing the window.location.hash=' ' in client.js

Javascript scraper logging in

I seem to be doing something wrong.
I have a student website that I want to scrape, but first I need to log in. Currently I have a python scraper that does it. The website logs in with a post request to a url containing a sid and PIN.
var login_url = 'https://example.com';
var formData = {
sid: 'username',
PIN: 'password'
}
How would I go about creating the same scraper but with javascript? I have seen the request library, which seems like what I want to use but cannot get it to work.
You need to use the request module to POST the form data to your endpoint. The response from the server will be in the call back to the .post() method.
const request = require('request');
// do not reassign "request", if you need to set properties us a different variable
// use the action= value from the form for the URL
const url = 'https://central.carleton.ca/prod/twbkwbis.P_ValLoginn';
const data = {
sid: 'username',
PIN: 'password',
};
request.post({ url: url, formData: data }, (err, response, body) => {
if (err) {
console.log('failed', err);
} else {
console.log('the response', body);
}
});
If you are interesting in parsing the resulting HTML I recommend using CheerioJS - much like jQuery but server side.

How do I transfer data from a client-side form input to a server-side Nodejs script?

I'm trying to implement functionality which takes data from form inputs on the client-side and sends it to the server to be processed by my Nodejs backend.
I've got the server-side function working, but I'm unsure as to how I would go about sending the data from the client-side form to my backend server via the $.ajax GET request that submits the form.
The code I have so far:
Server side function:
app.get('/id', function(req,res) {
var query = "SELECT * FROM Control";
connection.query(query, function() {
console.log(query);
});
});
Client side function:
function select()
{
$.ajax({
type: 'get',
url: '/id',
success: function(data) {
var ceva = data;
console.log('#ceva');
},
error: function(err) {
console.log(err);
}
});
}
You want to use a POST request rather than a GET request. Doing so will allow you to send data along with the request that you can then use in your query on the server side and send the response back to your client. Like so:
Client Side
function select() {
var id = $('#My-ID-Input').val();
$.ajax({
type: 'post',
url: '/id',
data : {
id : id
},
success: function(data) {
var id = data.id;
$('#My-ID-Input').val(id);
},
error: function(err) {
console.log(err);
}
});
}
Server Side
app.post('/id', function(req, res) {
var data = req.body;
var id = data.id;
var query = "SELECT * FROM Control WHERE id=" + id;
connection.query(query, function(error, result) {
console.log(result);
res.send(result);
});
});
GOTCHA!
You need to make sure that you have the express bodyparser
middleware implemented into your server to ensure that the data sent
as the body of the post request is then parsed into an object literal
on the server side. In your server module/file, you'll need to include the following code, and ensure that you've npm install body-parser:
var bodyParser = require('body-parser');
app.use( bodyParser.json() );

Categories