Specifically add browser to POST request in Node.js - javascript

I have a proxy endpoint in a Node.js service that is forwarding POST requests as follows:
request.post(
fullURL,
{ form: req.body },
function (error, response, body) {
if (response){
res.status(response.statusCode).send(body);
}
else {
res.status(500).send("ERROR");
}
}
);
And this is forwarding to a Spring Boot service that is attempting to extract the browser info via:
String browser = request.getHeader("User-Agent");
But this is always empty when being forwarded through the proxy. So how can I specifically set User-Agent in the request?
NOTE: req.headers['user-agent'] from the original incoming request is all present and correct, and ready to be injected into forwarding POST request

From what I can see, your only issue is that you're not actually relaying the user-agent header, but you are reading it. Pass the header object with your POST request like so:
headers: {
'User-Agent': userAgentVariable
}
Haven't tested this myself, but try the following:
request.post(
fullURL,
{
form: req.body,
headers: {
'User-Agent': request.getHeader("User-Agent")
}
},
function (error, response, body) {
if (response){
res.status(response.statusCode).send(body);
}
else {
res.status(500).send("ERROR");
}
}
);

Related

Cannot read POST response body from external api in firebase cloud functions

I have a cloud function which makes an http POST request to the LinkedIn API in order to retrieve an access token. The problem is that I cannot read the body of the response, it's always undefined.
Here's the code
exports.linkedinToken = functions.https.onRequest((req, res) => {
let url = "https://linkedin.com/oauth/v2/accessToken?...REQUIRED_PARAMS...";
request.post(url, {json: true}, (err, response, body) => {
if (!!err) { // this is never happening
console.log(err);
throw err;
} else {
console.log(response.body); // this is always undefined
console.log(body); // this is always undefined
}
});
If I try the same request with Postman or curl it works perfectly, and I cannot really understand why.
Before this request, I made another GET request to the linkedin API and it works normally. Maybe there's a problem with POST requests.
I think you are missing headers.
var request = require('request');
request.post({
headers: {
'content-type' : 'application/x-www-form-urlencoded',
'cache-control' : 'no-cache'
},
url: url
}, function(error, response, body){
console.log(body);
});

Request package: response.body is not JSON

I am using nodejs request module to fetch data from stackexchange api. However, I do not understand the body of the response
��V�n�6������$_��Ң�C��MQc�Ԓ���wHɉs�.l��s�>��㆕ڋ�
<C2��ݓ-�T��x]OȄ���T���Y�Z��2Cs�{ד;��<Ū�å��Ѭ�՚�O�x����i��+��x:��0�d$��ʬ1(��z]�R2�[�d�xnL��0��� %����T�a���f��hM�wV��Z�߭���($�z �UA�+AJ�w�P;'�BY���L�6�n䖩��;����֏��X?��"B�'�Q5�z[�v+*ka0�(B݉�ޠ�i�)�1D�D���o�ٯ�&��d:FgPNsA}E�`:�
1H?j���Fy4O�h��;'�O����#2�H�=`Z)|Rq��J�o+�_�����I��~�d�[TI��pSظ�}��y�H8����-4
<p���#�X�{�Y�d�4�jq��Z;����K�����}��:pu���NGt��ԟDӉ%l��M��8�&4������#d*� �Eʔbj�-, �u��
IpE��!Y�� `;�5��yX-�b)N&S)0�6�-���f��Q��8��f"i�+m�6.�M�sr�B�ST�x��y�6���l�3����
<a[48�Mp#��(���b�'���RA�D�m���n\4.8�.��.���v5jjU���Y��25S�-�]���z�T��'�:�޲�d&�I[��7pv�:��Ф(�3���$g$�1��׮z`�0��=�+���5px��x����r��u�-�������V�}ڼ����,8L��o�%�ږ��wc�#mM��&v�N|���Z�q�pZ?J������K[���Rd��BfX/�O�#ֿ���˷
��3T�mGa�`۴�7�ƕ"[���T�}�����v_�T�#��A����g}����ӌN�]��K�,$΁gJ<��z?���ђ
k��Q�a ����$V66�g�? �H�����1��5�c�Xi���0[i��܍�
�̞Ϝl�*��8d�����C����R0�i3��dfI�b�k]��^he�QX3�Ҏ ;�5/���X�r(��7Z�A.���tR�9D*�F�ű���V�w�o.�ɪt))4�_ҐUI<��ӻb%���'�d|��3���
I want the body to be in JSON format.
I tried using JSON.parse(body) but it throws this error
undefined:1
� ^
SyntaxError: Unexpected token in JSON at position 0
Here is the code on my nodeJS app
var questionId = req.params.id
request.get('https://api.stackexchange.com/2.2/questions/'+questionId+'?order=desc&sort=activity&site=stackoverflow&filter=!9Z(-wwYGT',
{json:true}, (error, response, body) => {
if(error) res.status(500).json(error)
else{
res.status(200).send(body)
}
})
Stack Exchange is requiring gzip. The request module isn't requesting it by default, so it assumes that it doesn't need to decode it.
Enable gzip on the request:
const request = require('request');
request.get(
{
url: 'https://api.stackexchange.com/2.2/questions/53684484?order=desc&sort=activity&site=stackoverflow&filter=!9Z(-wwYGT',
json:true,
gzip: true
}, (error, response, body) => {
console.log({error, response, body});
}
);
https://repl.it/repls/AppropriateSarcasticFilesize
Assuming request is the npm request module, the get method allows only two parameters (URL or options with URL, and callback) while you are passing URL and options separately.
For example:
request.get({
uri: 'https://api.stackexchange.com/2.2/questions/'+questionId+'?order=desc&sort=activity&site=stackoverflow&filter=!9Z(-wwYGT',
json: true,
},(error, response, body) => {
// ... callback here
});

Axios HTTP requests returns into an error (Access-Control-Allow-Origin)

I'm trying to make http post requests with Axios in JavaScript. The request was working fine, but then I tried to use cookies. As my backend I'm using an Express/Nodejs Server on http://localhost:8000, while my frontend is a react npm test server on http://localhost:3000.
My backend looks like this:
const express = require('express');
const cookieparser = require('cookie-parser');
const cors = require('cors');
const app = express();
app.use(cookieparser());
app.use(cors());
app.post("/request/status/check", (req, res) => {
if(req.cookies.gitEmployee != null){
res.status(200).send({res: 1, employeeName: req.cookies.gitEmployee.username, fullname: req.cookies.gitEmployee.fullname});
} else if(req.cookies.gitCompany != null){
res.status(200).send({res: 2, companyName: req.cookies.gitCompany.companyName, fullname: req.cookies.gitCompany.fullname});
}else{
res.status(200).send({res: 0});
}
});
app.post("/request/testcookie", (req, res) => {
res.cookie("gitEmployee", null);
res.cookie("gitEmployee", {
username: "testusername",
fullname: "Test Username"
}).send({res: 1});
});
So, as a short description: I'm setting a test cookie by posting a request to http://localhost:8000/request/testcookie. The response should be an JSON object where res = 1. Also, I'm trying to get information out of the cookie by posting a request to http://localhost:8000/request/status/check. In this case the response should be the object {res:1 , employeeName: "testusername", fullname: "Test Username"}.
I tried this concept with a REST Client called Insomnia (something like Postman) and it worked perfectly.
Then I wrote a helper-class for my React Application and for the Http request I'm using Axios.
import axios from 'axios';
class manageMongo {
authstate(){
return new Promise((resolve, reject) => {
axios("http://localhost:8000/request/status/check", {
method: "post",
data: null,
headers: {
"Access-Control-Allow-Origin": "*"
},
withCredentials: true
})
.then(res => {
console.log(res.data);
if(res.data.res === 0){
resolve(false);
}
if(res.data.res === 1){
resolve(true);
}
if(res.data.res === 2){
resolve(true);
}
});
});
}
setTestCookie(){
axios("http://localhost:8000/request/testcookie", {
method: "post",
data: null,
headers: {"Access-Control-Allow-Origin": "*"},
withCredentials: true
})
.then(res => { console.log(res)});
}
}
export default manageMongo.prototype;
When I execute these functions, I'm getting the same error of both of them (of course with different urls):
Failed to load http://localhost:8000/request/testcookie: Response to
preflight request doesn't pass access control check: The value of the
'Access-Control-Allow-Origin' header in the response must not be the
wildcard '*' when the request's credentials mode is 'include'
I already know that it's because of the withCredentials setting in the requests. I added these settings because I want to pass cookies through these requests and if I don't add withCredentials, the /request/status/check request always returns {res: 0} even if I set a cookie before.
I don't know, if this will change if the I set withCredentials = true but i read that in multiple threads. If you know an other working method to pass cookies through these requests even without axios please share it here! Because that is, what I want to achieve.
The problem seems to be you have set
'Access-Control-Allow-Origin': *
Try setting it to your actual origin, for example
'Access-Control-Allow-Origin': 'http://localhost:8000'
or
'Access-Control-Allow-Origin': 'http://localhost:3000'
Whichever the request originates from.

How to find where form parameters are stored and use them in Request

I am trying to scrape https://www.freelance.nl/opdrachten/zoeken for data using Request and Cheerio but I am running into issues posting search terms.
I cannot see where the search string and selected category are sent during the post when using the site and how I can use them in Request to automate searches from my node application.
Basically I want to be able to send different search terms using Request then I can scrape the returned html for the data I need.
So far I have this:
request.post('https://www.freelance.nl/opdrachten/zoeken', { form: { key: 'value' } },
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body)
}
}
);
But as I cannot see where the form data is stored in dev tools, I cannot send the correct values in the 'form' object. I'm pretty sure it's in request payload, but how do I get to that from my node application?
Is there an easier way to do this? Am I completely wasting my time?
I've slighly modified your code:
payload = {'projectFilterForm[keywords]':'javascript','projectFilterForm[category][]': '1'}
request.post('https://www.freelance.nl/opdrachten/zoeken', { data:payload },
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body)
}
}
);
Open your eyes ;) On the bottom of your image, look at Request Payload
projectFilterForm[keywords]
projectFilterForm[category][]
projectFilterForm[province][]
Update
var request = require('request');
var querystring = require('querystring');
require('request').debug = true;
var data = querystring.stringify({
'projectFilterForm[keywords]': 'java'
});
var options = {
followAllRedirects: true,
uri: 'https://www.freelance.nl/opdrachten/zoeken',
method: 'POST',
headers: {
'Content-Length': Buffer.byteLength(data),
'cache-control': 'no-cache',
'Content-Type': 'multipart/form-data',
'origin': 'https://www.freelance.nl',
'referer': 'https://www.freelance.nl/opdrachten/zoeken',
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36'
}
};
var req = request(options, function (error, response, body) {
console.log(body);
});
req.write(data);
req.end();
I tried everything =)) Nothing... after redirect, we get default page. Maybe they use some session bases protection?
This is not node's problem. I tried to do this even in chrome's postman extension with no luck.

Sending parameters to an API using node.js

I have worked with REST APIs in Python but have no idea how to use them in node.js. I'm trying to build an application that pulls data from a user's smartsheet account. The smartsheet API page gives cURL examples. Could you please tell me how to call this API and pass parameters to it in node.js?
Thanks in advance.
You can use request module. Since I don't have an access token I am getting {"errorCode":1002,"message":"Your Access Token is invalid."}
var request = require('request');
var options = {
url: 'https://api.smartsheet.com/1.1/sheets',
headers: {
'Authorization': 'Bearer ACCESS_TOKEN'
}
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
var info = JSON.parse(body);
console.log(info);
} else {
console.log(error);
console.log(body);
}
}
request(options, callback);

Categories