Nodejs request behaves differently than Postman and Curl - node.js

I've been messing with that for a while now and can't seem to figure it out... I'm trying to send a POST request to a device (what device doesn't matter I guess) in order to change it's IP address. Usually, the setup is done through the browser, so I'm trying to emulate that request. It seems to be working fine when I make the request with Postman or Curl but not with the request module from Node.js.
All requests return a 200 OK status code but the latter seems to be not accepted. This is the request I perform using Postman:
POST /configuration_tab/ajax_comb_table_save/network_config/network_config_schema HTTP/1.1
Host: 192.168.1.250
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: PHPSESSID=mg37okvhkr1eqv1okq99i98i62
Cache-Control: no-cache
Postman-Token: 234ece69-c3f8-2d29-34a5-c40f8e64f708
form=Hostname%3D%26IPv4mode%3Dstatic%26IPv4address%3D192.168.1.250%26
IPv4netmask%3D255.255.255.0%26IPv4gateway%3D0.0.0.0%26DNSmode%3Dmanual%26
IPv4DNS1%3D%26IPv4DNS2%3D%26IpAddrCnflctDetectEnbl%3Denable%26NtpServer%3D%26
SyslogServer%3D%26SyslogPort%3D514%26SshServerEnable%3Denable
This is what I sent through curl:
curl -X POST "http://192.168.1.250/configuration_tab/ajax_comb_table_save/network_config/network_config_schema"
-H "Content-Type:application/x-www-form-urlencoded; charset=UTF-8"
-H "Cookie:PHPSESSID=mg37okvhkr1eqv1okq99i98i62"
-d "form=Hostname%3D%26IPv4mode%3Dstatic%26IPv4address%3D192.168.1.250%26IPv4netmask%3D255.255.255.0%26IPv4gateway%3D0.0.0.0%26DNSmode%3Dmanual%26IPv4DNS1%3D%26IPv4DNS2%3D%26IpAddrCnflctDetectEnbl%3Denable%26NtpServer%3D%26SyslogServer%3D%26SyslogPort%3D514%26SshServerEnable%3Denable"
Again, both of them work fine. Now, this is the code I was using to try the same thing via Node:
let body = "form=Hostname%3D%26IPv4mode%3Dstatic%26IPv4address%3D192.168.1.250%26IPv4netmask%3D255.255.255.0%26IPv4gateway%3D0.0.0.0%26DNSmode%3Dmanual%26IPv4DNS1%3D%26IPv4DNS2%3D%26IpAddrCnflctDetectEnbl%3Denable%26NtpServer%3D%26SyslogServer%3D%26SyslogPort%3D514%26SshServerEnable%3Denable"
request({
url: "http://192.168.1.250/configuration_tab/ajax_comb_table_save/network_config/network_config_schema",
method: "POST",
headers: {
"Cookie": "PHPSESSID=mg37okvhkr1eqv1okq99i98i62",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: body
}, (err, resp) => {
// Do whatever...
});
Does anyone have an idea what might be different or anything I'm missing? Any help would be appreciated.

Related

Axios Request From Vue/Nuxt App Timed Out, No Response From Server, But Same Curl Request Gets Response

I have a Nuxt application which makes requests to an IIS server running NodeJS as an API. The IIS server is set to only accept requests from the frontend Vue application server (ports 80 and 443).
When I run the below from the command line on the frontend server I get a proper response and can see the request hit the IIS backend server via logs:
//This WORKS
curl --cacert certbundle.crt https://xx.xx.xx.xx/cost/woapprovedqueue
I'm making a seemingly similar request with Axios in my Nuxt application on the same frontend server where I ran the curl request but I don't get any response from the server and the request times out after some time with the error net::ERR_CONNECTION_TIMED_OUT.
When I copy the failed executed request from Chrome DevTools as cURL I get the following:
curl 'https://xx.xx.xx.xx/cost/woapprovedqueue' \
-H 'sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Referer: https://xxx.yyy.com/' \
-H 'DNT: 1' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36' \
--compressed
If I take the above curl command to the frontend again and add my --cacert certbundle.crt, it works.
What do I need to do to make this request work with Nuxt/Axios? Is it an SSL/Certificate issue? I'm leaning towards "no" since I don't get ANY response and nothing shows in the backend API server logs. You'd think we would at least get a cert issue response.
I have a file in plugins/axios.js:
export default function ({ $axios, store, app }) {
$axios.defaults.httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
}
I load the plugin with this in nuxt.config.js: plugins: [ '#/plugins/axios' ]
I have an axios baseURL in nuxt.config.js: axios: { baseURL: 'https://xx.xx.xx.xx' }
On my .vue page I have the following which makes the request:
//This does NOT seem to work. I get no response, timed out, and nothing in server logs.
this.queue = await this.$axios.$get('/cost/woapprovedqueue');
Any and all help will be VERY much appreciated as I've been trying to figure this out for a while now. :)
Update, providing the fetch query copied from Google Chrome Dev Tools:
fetch("https://xx.xx.xx.xx/cost/woapprovedqueue", {
"headers": {
"accept": "application/json, text/plain, */*",
"sec-ch-ua": "\"Google Chrome\";v=\"89\", \"Chromium\";v=\"89\", \";Not A Brand\";v=\"99\"",
"sec-ch-ua-mobile": "?0"
},
"referrer": "https://xxx.yyy.com/",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": null,
"method": "GET",
"mode": "cors",
"credentials": "omit"
});
It turns out the issue was related to HTTPS/SSL. I needed to set up and use a proxy. I was getting a CORS related issue which only showed up when inspecting the network events in Firefox (Chrome did not show this level of detail for some reason). These are the settings that eventually worked in nuxt.config.js:
axios: {
https: true,
proxy: true,
prefix: '/api/',
},
proxy: {
'/api/': { target: process.env.API_BASE_URL, secure: false, pathRewrite: {'^/api/': ''} },
},

curl command equivalent in nodejs

I have the curl command here which is working as I want:
curl -X POST -H "Content-Type: application/json" -d #cats.json http://localhost:8080
And I would like to get help on translating this into nodejs
I currently have localhost set up and my goal is to display data stored in a JSON file. I currently copy and paste the data into postman and post the data to the localhost but I want to not use postman. The curl command was useful but I want to incorporate it into my code.
I've tried
var request = require('request');
request.post({
headers: {'content-type' : 'application/json'},
url: 'http://localhost/8080',
body: "someData"
}, function(error, response, body){
console.log(body);
});
I've tried this but it doesn't provide the same outcome as the curl command does where the data appears in my localhost
In postman, you can export NodeJS request code out:
Click on Code
Then select NodeJS -> Request.
Copy to Clipboard

Self-hosted Parse Platform RESTful API access

I'm using Parse for some quick MVP app development to prove some concepts. Everything is working fine and I'm simply trying to extend the abilities of our app by setting up some 3rd party integrations etc.
I would like to access my Cloud Code functions via the RESTful api, as documented here
I've changed the server address, but have no luck connecting and pulling the data.
I am using Node.js to connect to the REST api, which is being hosted on Heroku.
var options = {
host: 'https://###############.herokuapp.com',
port: 443,
path: '/parse/functions/'+req.param('text'),
method: 'POST',
headers: {
'X-Parse-Application-Id': '##############',
'X-Parse-REST-API-Key': '###########'
}
};
https.get(options, function(resp){
resp.on('data', function(chunk){
//do something with chunk
res.send(chunk)
});
}).on("error", function(e){
console.log("Got error: " + e.message);
res.send(e)
});
So far no luck. Any suggestions?
Hard to tell what exactly is wrong without seeing the Parse Server configuration, the Cloud Code function, and more importantly the server's response, but here's what worked for me:
curl -X POST -H "X-Parse-Application-Id: XYZUASDASDA" -H
"X-Parse-REST-API-Key: XYZUASDASDA" -H "Content-Type:
application/json" -d '{}'
http://localhost:3000/parse/functions/averageStars
Result: {"result":"Hello"}
Here's my test Cloud Code function:
Parse.Cloud.define('averageStars', function(request, response) {
response.success('Hello'); });
As a quick test, I suggest:
Try using CURL
Try the test function above

Fetch API cannot load ... No 'Access-Control-Allow-Origin' header

I got
a rest api deployed on heroku
a react app deployed on heroku
the react app tries to get data from the rest api using whatwg-fetch.
var header = {"Content-Type": "multipart/form-data", 'Origin': 'https://foo.bar', 'Access-Control-Request-Method': 'GET', 'Access-Control-Request-Headers': 'X-Requested-With'};
var options = {method: 'GET', credentials: 'include', headers: header};
fetch('https://myrest.api/foo', options)...
But I can't get any data, it say's
Fetch API cannot load https://foo.bar.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://foo.bar' is therefore not allowed access.
The response had HTTP status code 403.
If an opaque response serves your needs, set the request's mode to 'no-cors'
to fetch the resource with CORS disabled.
When I try to get the data with curl it works
curl -H "Origin: https://foo.bar" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: X-Requested-With" \
-X GET --verbose https://myrest.api/foo -D header.txt
and the response header (from the curl command)
HTTP/1.1 200
Server: Cowboy
Connection: keep-alive
Access-Control-Allow-Origin: https://foo.bar
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 09 Dec 2016 23:52:57 GMT
Via: 1.1 vegur
Cors is enabled in the spring boot application via #CrossOrigin
Thanks in advance
Best Regards
It seems that you are trying to access from one domain https://foo.bar into another domain at https://myrest.api and that is the reason for that error.
You have 2 options:
1) Merge this 2 apps into one single domain on Heruko, React and the Api apps will be under https://foo.bar domain for example and that will work for you.
2) Allow the client app domain at https://foo.bar to access into your api domain at https://myrest.api by adding "Access-Control-Allow-Origin" header into the api app:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
next();
});

Node.js res.setHeader('content-type', 'text/javascript'); pushing the response javascript as file download

Scenario: Consider the following code to give a JavaScript as a response from the Node.JS server.
var http = require('http');
http.createServer(function (req, res) {
var JS_Script = 'function Test() { alert("test success")}';
res.setHeader('content-type', 'text/javascript');
res.send(JS_Script);
}).listen(8811);
Issue: It forcing the browser to download the file.
Question: How can I make it to render on browser?
Note: Working in .net web service with same HTTP-header: 'content-type', 'text/javascript'
So, Its clear following statement does not hold good.
If you want a web browser to render the HTML, you should change this to:
Content-Type: text/html
Update: On inspecting the content-type during the download its application/octet-stream
But the same when I hit a request with curl, the following is the output:
C:\>curl -is http://localhost:8811/
HTTP/1.1 200 OK
Content-Type: text/javascript
Content-Length: 166
Date: Tue, 09 Apr 2013 10:31:32 GMT
Connection: keep-alive
function Test() { alert("test success")}
Use application/javascript as content type instead of text/javascript
text/javascript is mentioned obsolete. See reference docs.
http://www.iana.org/assignments/media-types/application
Also see this question on SO.
UPDATE:
I have tried executing the code you have given and the below didn't work.
res.setHeader('content-type', 'text/javascript');
res.send(JS_Script);
This is what worked for me.
res.setHeader('content-type', 'text/javascript');
res.end(JS_Script);
As robertklep has suggested, please refer to the node http docs, there is no response.send() there.
You can directly set the content type like below:
res.writeHead(200, {'Content-Type': 'text/plain'});
For reference go through the nodejs Docs link.

Resources