I am trying to send a post request to a URL, I did this in python with the following code and it worked like a charm and I got a [Response <200>], but since I needed to use this in a website, I switched over to JS and tried to recreate the same functionality, but for some reason I'm getting a [Response <403>] even tho all my auth tokens and headers and everything is same as the python code.
Python Code -
url = "https://discord.com/api/v8/channels/801784356711956522/messages"
auth = ""
headers = {"Authorization": auth,
'Content-Type': 'application/json', 'referer': "https://discord.com/channels/801784356217421874/801784356711956522"}
payload = {'content': 'Test' , 'nounce': 802056256326991872, 'tts': False}
response = requests.post(url, data=json.dumps(payload), headers=headers)
print(response)
JavaScript Code -
onst url = "https://discord.com/api/v8/channels/801784356711956522/messages"
const auth = ""
const headers = {"Authorization": auth,
'Content-Type': 'application/json',
'referer': "https://discord.com/channels/801784356217421874/801784356711956522"}
const options = {
headers : headers,
}
const data = JSON.stringify({'content':"Test" , 'nounce': 802056256326991872, 'tts': false})
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
const req = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', (d) => {
process.stdout.write(d)
})
})
req.on('error', (error) => {
console.error(error)
})
req.write(data)
req.end()
In your python code, you made a POST request but in JavaScript code, you made a GET request because you did not provide the method option.
It is specified in https.request options documentation:
method A string specifying the HTTP request method. Default:
'GET'.
To make POST request modify like this
const options = {
headers : headers,
method: "POST"
}
Also, you need to add URL since you did not provide hostname and path in the options.
const req = https.request(url, options, (res) => {
// ...
})
const querystring = require('querystring');
const https = require('https');
var postData = querystring.stringify({
'msg' : 'Hello World!'
});
var options = {
hostname: 'domain.com',
port: 443,
path: '/yow-path',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
}
};
var req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.write(postData);
req.end();
Related
Hello I have tried to use the instagram api to get a connection token. I first tested it on postman and this is what I did:
I used this link to make a request post to the instagram api:
https://api.instagram.com/oauth/access_token?client_id=clientid&client_secret=clientsecret&grant_type=authorization_code&redirect_uri=https://mysite/&code=thecode
The api gives me an error: Missing required field client_id
But when I set the content type to x-www-form-urlencoded everything works fine on postman.
So I tried to do the same thing in javascript with the node module request. I tried to do the same thing as on postman with the module but it does not work... Here is my code:
request(`https://api.instagram.com/oauth/access_token?client_id=clientid&client_secret=clientsecret&grant_type=authorization_code&redirect_uri=https://mysite/&code=` + code, {
method: 'POST',
headers: {"Content-Type": "x-www-form-urlencoded"}
}, (error, response, body) => {
console.log('body:', body)
})
As per MDN, the content type should be application/x-www-form-urlencoded
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST
Update:
You should read the node doc : https://nodejs.dev/learn/making-http-requests-with-nodejs
Get method:
const https = require('https');
const options = {
hostname: 'api.instagram.com',
path: '/oauth/access_token?client_id=clientid&client_secret=clientsecret&grant_type=authorization_code&redirect_uri=https://mysite/&code=thecode',
method: 'GET',
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "Accept-Encoding"
}
};
const req = https.request(options, (res) => {
// ...
});
Post method:
var headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "Accept-Encoding"
};
var options = {
url: 'https://api.instagram.com/oauth/access_token',
method: 'POST',
headers: headers
};
var form = {
grant_type:'urn:ietf:params:oauth:grant-type:jwt-bearer',
client_id: 'id',
client_secret: 'secret'
redirect_uri : 'https://mysite/&code=thecode'
};
var request = https.request(options, function(response) {
// do stuff
});
request.write(querystring.stringify(form));
request.end();
I've been trying to send a JSON data using fetch but the backend receives an empty object.
In my Client JS I have
const user = "company1";
const username = "muneeb";
const data = {user, username};
fetch("http://127.0.0.1:3000/users/api/login", {
method: 'POST',
body: JSON.stringify(data)
}).then((response) => {
console.log(response);
});
The server side has:
router.post('/users/api/login', async (req, res, next) => {
try {
// console.log(request.body);
const request = JSON.stringify(req.body);
let imageTitles = [];
console.log(request);
*its random from here on out but you get the idea*
await components.getImages(imageTitles);
const finalKey = imageTitles.join("");
let images = await components.output(req.body.user ,req.body.username);
res.send(components.jsonConverter(imageTitles, images)); //---Top priority
db.setPassword(req.body.user, req.body.username , finalKey);
} catch (err) {
console.log(err);
res.send(err).sendStatus(500);
};
})
A few things I have already tried :
It works perfectly in Insomnia(postman).
express.json() is present , it helped me go from undefined to blank JSON.
I have enabled cors settings.
That's it for now.
The body parser express.json will only be applied for requests with Content-Type: application/json. You have to add the content type to your fetch call:
fetch("http://127.0.0.1:3000/users/api/login", {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
Getting a dreaded JSON error .
I am using an external API that allegedly takes a POST to add a user to a group.
in my nodeJS express app - I want to pass-thru the data coming from my app to the external API.
my "GET" methods work - but now I am trying to take a form submitted to my app, and pass the data to an external API using "POST".
Here is the code I am testing (assume the api url and credentials are correct - and NOT the issue)
I have tested the external API passing the same JSON object directly to the external API using Postman, and it works without error.
const express = require('express');
const router = express.Router();
const https = require('https');
function callExternalAPI( RequestOptions ) {
return new Promise((resolve, reject) => {
https.request(
RequestOptions,
function(response) {
const { statusCode } = response;
if (statusCode >= 300) {
reject(
new Error( response.statusMessage )
);
}
const chunks = [];
response.on('data', (chunk) => {
chunks.push(chunk);
});
response.on('end', () => {
const result = Buffer.concat(chunks).toString();
resolve( JSON.parse(result) );
});
}
)
.end();
})
}
router.get('/thing', /*auth,*/ ( req, res, next ) => {
callExternalAPI(
{
host: 'api_url',
path: '/list',
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + new Buffer( auth_un + ':' + auth_pw ).toString('base64')
}
}
)
.then(
response => {
console.log(response);
}
)
.catch(
error => {
console.log(error);
}
);
});
router.post('/thing', /*auth,*/ ( req, res, next ) => {
callExternalAPI(
{
host: 'api_url',
path: '/addThing',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + new Buffer( auth_un + ':' + auth_pw ).toString('base64')
},
data: {
'group_id': req.body.group_id,
'person_id': req.body.person_id
}
}
)
.then(
response => {
console.log(response);
}
)
.catch(
error => {
console.log(error);
}
);
});
module.exports = router;
console logging the req.body looks lie this
{ group_id: '45b62b61-62fa-4684-a058-db3ef284f699', person_id: '3b1c915c-3906-42cf-8084-f9a25179d6b2' }
And the error looks like this
undefined:1
<html><title>JSpring Application Exception</title>
<h2>JSpring Exception Stack Trace</h2>
<pre>SafeException: FiberServer.parsers.parseJSONBuf(): JSON parse failed.
^
SyntaxError: Unexpected token < in JSON at position 0
Granted the console.log of the req.body does not have the required double quotes, but I think that is just the log dump format - but it might be munging the JSON. I have tried wrapping this in stringify; meaning something like this: data: JSON.stringify( req.body ) (but the same error occurs).
callExternalAPI(
{
host: 'api_url',
path: '/addThing',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + new Buffer( auth_un + ':' + auth_pw ).toString('base64')
},
**data: JSON.stringify( req.body )**
}
)
I am testing this in postman, having the body be 'raw json' with headers as 'application/json'
the body is this:
{
"group_id": "45b62b61-62fa-4684-a058-db3ef284f699",
"person_id": "3b1c915c-3906-42cf-8084-f9a25179d6b2"
}
You should try to write the POST payload in the request body instead of passing it inside the options object:
function callExternalAPI( RequestOptions ) {
const { data, ...options } = RequestOptions;
return new Promise((resolve, reject) => {
const req = https.request(
options,
function(response) {
const { statusCode } = response;
if (statusCode >= 300) {
reject(
new Error( response.statusMessage )
);
}
const chunks = [];
response.on('data', (chunk) => {
chunks.push(chunk);
});
response.on('end', () => {
const result = Buffer.concat(chunks).toString();
resolve( JSON.parse(result) );
});
}
);
req.write(JSON.stringify(data));
req.end();
})
}
In express you must use bodyParser
At the top of the file when you initializing your express app add this lines
const app = express()
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
https://medium.com/#adamzerner/how-bodyparser-works-247897a93b90
I was using Azure Speech rest api. And i tried it on post man with a .wav file and it successfully return the result. However, when i call api from my node.js code. It always return Unsupported Audio Format even though i give the same audio file. Can anyone tell me what's the difference of them? Or what did Postman do to make it work?
Below is how i call speech api by node.js.
'use strict';
const request = require('request');
const subscriptionKey = 'MYSUBSCRIPTIONKEY';
const uriBase = 'https://westus.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US';
const options = {
uri: uriBase,
body: 'speech.wav',
headers: {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key' : subscriptionKey,
'Transfer-Encoding': 'chunked',
'Expect': '100-continue',
'Content-type':'audio/wav; codec=audio/pcm; samplerate=16000'
}
};
request.post(options, (error, response, body) => {
if (error) {
console.log('Error: ', error);
return;
}
let jsonResponse = JSON.stringify(JSON.parse(body), null, ' ');
console.log('JSON Response\n');
console.log(jsonResponse);
});
You can try this
fs.readFile('/path/to/my/audiofile.wav', function (err, data) {
if (err) throw err;
var options = {
host: 'https://westus.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US',
method: 'POST',
headers: { 'Content-Type': 'audio/wav' }
};
var req = http.request(options, function(res) {
// Handle a successful response here...
});
req.on('error', function(e) {
// Handle an error response here...
});
// Write the audio data in the request body.
req.write(data);
req.end();
});
I'm just beginning to learn javascript and https requests. I'm working in Visual Studio 2017, I created a blank javascript console app from the template and added the following code.
const https = require('https');
const options = {
hostname: 'api.gdax.com',
path: '/products/BTC-USD/stats',
method: 'GET',
agent: false
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();
The response I get from the server is
{"message":"User-Agent header is required."}
When I navigate to https://api.gdax.com/products/BTC-USD/stats in my browser I get the correct response. How come I can't do the same in a javascript console?
That's because that specific API is blocking any request without the User-Agent header.
Just add the header, and it will work fine:
const https = require('https');
const options = {
hostname: 'api.gdax.com',
path: '/products/BTC-USD/stats',
method: 'GET',
agent: false,
headers: {
'User-Agent': 'something',
},
};
const req = https.request(options, res => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', d => {
process.stdout.write(d);
});
});
req.on('error', e => {
console.error(e);
});
req.end();
You need to set headers manually. See http documentation for all possible request options (this is the same for http and https).
try:
const options = {
hostname: 'api.gdax.com',
path: '/products/BTC-USD/stats',
method: 'GET',
agent: false,
headers: {
'User-Agent': 'Foo/1.0',
},
};
You need to explicitely set the User-Agent header in the headers property of your request options
const options = {
hostname: 'api.gdax.com',
path: '/products/BTC-USD/stats',
method: 'GET',
agent: false,
headers: { 'User-Agent': 'Mosaic/1.0' }
};