Multiple POST request issues in Node JS - javascript

so I have been building a web app and I have already implemented a POST request to request some JSON data to be sent to the Node JS server however when I try to add a second post for a different set of data now as an HTML form I receive a Cannot POST /x/ page, however, if I use the previous POST URL for the first set of data the data is sent correctly. Is there some issue with sending multiple POST requests? I have added some code below so you can see my working /foo/ JSON data request vs my non-working /basket/ HTML form request. Thanks a lot in advance.
Working Code:
app.post("/foo/", function(req, res) {
var myObject = req.body;
console.log(myObject);
for(var i = 0; i < myObject.length; i++){
var parsed = JSON.parse(myObject[i])
console.log(parsed.Item.ProductNo);
console.log(parsed.Item.Quantity);
}
var transporter = nodemailer.createTransport({
service: '*****',
auth: {
user: '*****',
pass: '*****'
}
});
Not working request:
app.post("/basket/"), function(req, res){
var body = req.body;
console.log(body);
}
Working foo request JS:
function sendBasket(){
fetch('/foo/', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: localStorage.getItem('basket')
}).then(res=>res.json())
.then(res => console.log(res));
console.log('Sending' + basketList + 'To email');
//console.log(localStorage.getItem('basket'));
//$.post("/foo/", localStorage.getItem('basket'), function(temp) {
// temp === "I am done";
//});
}
Not working HTML form request:
form#customerForm(method = 'post' action = '/basket/')
input(class='input' id='email' name='email' type='email' value='')
ul#listForBasket.listForBasket
input#butSubmit(type = 'submit' value = 'submit')

Answer: I'm still somewhat unsure how I fixed it but the issue has now been resolved, I believe it was due to the incorrect use of the Action attribute in the HTML form along with a badly structured fetch request in the JS file and also a badly structured server.js file. Huge thanks to u/fastidious-magician for being a great help in diagnosing my issues. Here is my final working second fetch request in JS:
function sendData(e){
e.preventDefault();
const email = document.getElementById("email").value;
const bodyToSubmit = { "email": email }
console.log(JSON.stringify(bodyToSubmit))
fetch('/foo2/', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify(bodyToSubmit)
}).then(res=>res.json())
.then(res => console.log(res));
}

Related

Creating tickets using Zendesk api with React

I working on intergrating a react app with the zendesk api for creating support tickets.
Till now i have completed the form flow, but when i making the request to the zendesk api i am getting 401.
I am using the api_key approach for this.
I am fairly new to zendesk, if anyone can help me regarding that.
Here is my code after user clicks submit.
const onSubmit = async () => {
try {
console.log('setInfo', info)
const data = { request: { subject: 'test', comment: { body: 'testdesc' } } }
const user = 'test#test.com'
const api_token = 'some_api_key'
const url = 'https://url.zendesk.com/api/v2/tickets.json'
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'no-cors',
headers: {
'Content-Type': 'application/json',
Authorization: api_token,
// 'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
console.log('respone', response)
} catch (error) {
console.log('respone error', error)
}
}
It looks like you're not sending the right authorization header. According to Zendesk API reference you need to use the following format for the credentials:
{email_address}/token:{api_token}
Example:
jdoe#example.com/token:6wiIBWbGkBMo1mRDMuVwkw1EPsNkeUj95PIz2akv
After base64-encoding the resulting string, add it to the Authorization header as follows:
Authorization: Basic amRvZUBleGFtcGxlLmNvbS90b2tlbjo2d2lJQldiR2tCTW8xbVJETXVWd2t3MUVQc05rZVVqOTVQSXoyYWt2

issue with making a call using fetch and jwt

*My goal here is to get the location of bikes from a bike-sharing company's API.
I did Steps 1 and 2 using Postman. but ill try to integrate it into my code once I get the hang of it.
The first step is to verify your email and generate an Auth token. This requires only a verifiable email address. Make a POST request to https://web.spin.pm/api/v1/magic_links with the body:
{"email": "sampleemail#gmail.com"}
From there, you will need to find the token within your email. This token needs to be sent with a POST request to
https://web.spin.pm/api/v1/auth_tokens with the body:
{
"grant_type": "magic_link",
"magic_link": {
"email": "<email>",
"token": "<token>"
}
}
This request returns a JSON that looks like this: {"jwt":"eyJ0eXAiOiJ.....cXVLw","refreshToken":"2cb07....bab5030","existingAccount":false}
To get the position of vehicles so a GET-Request to https://web.spin.pm/api/v3/vehicles?lng=-77.0146489&lat=38.8969363&distance=&mode= User Header Authorization: Bearer to Authenticate and use the jwt-Token we got from the Auth request.
You will get something like this as return JSON {"vehicles":[{"lat":37.69247,"lng":-122.46595,"last4":"3595","vehicle_type":"bicycle","batt_percentage":null,"rebalance":null}, … ]}
Step 3 is done using (async/awit function) using fetch where I am having the problem with. I copy-pasted the jwt in my .env file and set up the proper headers.
I get a 401 response when making the call. when I tested step 3 using postman everything seems to work fine.
I have attached a screenshot of the error in this post. Hopefully its more clear, Thanks in advance.
const fetch = require("node-fetch");
require('dotenv').config();
async function getBikes()
{
const lat = '38.897574612438575';
const lng = '-77.01855164084469';
const api_url = `https://web.spin.pm/api/v3/vehicles?lng=${lng}&lat=${lat}&distance=&mode=`;
const jwt_key = process.env.BERER_KEY;
try{
const config = { method: 'GET',
headers: {json: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer'+ jwt_key
} },
rejectUnauthorized: false
};
const response = await fetch(api_url,config );
const data = await response.json(); //response.json() //headers //.jwt; //response.json()
if (response.ok)
{
console.log("STATUS CODE IS: "+response.status);
console.log('My JWT:', response);
return data;
}
else{
console.log("something went wrong ");
console.log("STATUS CODE IS: "+ response.status);
console.log( response);
}
} catch (error) {
console.log(error);
}
}
const y = getBikes();
console.log(y)
BEARER_KEY=eyJhbGciOiJIUzI1NiJ9.eyJ1c2V

Send data in a http post in angular 2?

I'm trying to send data with http post following differents threads, but I can't do it.
I need to send this data, tested in postman.
Headers.
Content-Type: application/x-www-form-urlencoded
Authorization: Basic user:pass
Body.
grant_type: password
scope: profile
This is my code.
login() {
let url = URL_LOGIN;
let headers = new Headers(
{
'Content-Type': 'application/json',
'Authorization': 'Basic user:pass'
});
let body = {
'grant_type': 'password',
'scope': 'profile'
}
return this.http.post(url, body, { headers: headers })
.map((response: Response) => {
var result = response.json();
return result;
})
}
Thanks in advance!!
There are two things you need to modify:
Your headers passed into the http post method missed one step. It should contain the following:
let options = new RequestOptions({ headers: headers });
Ensure you import RequestOptions from #angular/http
Then pass options into your post method as follows:
return this.http.post(url, body, options)...
The http post method body can only be a string. Therefore, it should be as follows:
let body = 'grant_type=password' + '&scope=profile';

how do I make a post and get request with ReactJS, Axios and Mailchimp?

I am new to ReactJS and I am trying to build this app that need to use mailchimp so the user can subscribe for newsletter. I need to make a request using axios? can someone guide me through this? where do i put my api key? Did I do it correct in the bellow code? i put my mailchimps username in 'username' and my apikey in 'xxxxxxxxxxxxxxxxxxx-us16', however, i got the 401 error saying Unauthorized, BUT my console did say Fetch Complete: POST and caught no error.
import React, {Component} from 'react';
import './Subscribe.css';
class Subscribe extends Component {
sub = () => {
let authenticationString = btoa('username:xxxxxxxxxxxxxxxxxxx-us16');
authenticationString = "Basic " + authenticationString;
fetch('https://us16.api.mailchimp.com/3.0/lists/xxxxxxxxx/members', {
mode: 'no-cors',
method: 'POST',
headers: {
'Authorization': authenticationString,
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
email_address: "somedude#gmail.com",
status: "subscribed",
})
}).then(function(e){
console.log('complete')
}).catch(function(e){
console.log("fetch error");
})
};
render () {
return(
<div>
<button onClick={this.sub}> subscribe </button>
</div>
);
};
};
In the documentation, the curl example uses the --user flag. Using this to convert curl commands to an equivalent js code, you need the 'auth' property on the option object of the fetch to make it work.
fetch('https://us16.api.mailchimp.com/3.0/lists/xxxxxxxxx/members', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
email_address: "somedude#gmail.com",
status: "subscribed",
},
auth: {
'user': 'username',
'pass': 'xxxxxxxxxxxxxxxxxxx-us16'
})
})
It took me a while to get the syntax right for this. This is an example of a working request using nodejs in a server-side-rendered reactjs app using axios.
It appears "get" requests won't work for this method because of the 401 error: MailChimp does not support client-side implementation of our API using CORS requests due to the potential security risk of exposing account API keys.
However, patch, put, and post seem to work fine.
Example (using async / await)
// Mailchimp List ID
let mcListId = "xxxxxxxx";
// My Mailchimp API Key
let API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxx-us12";
// Mailchimp identifies users by the md5 has of the lowercase of their email address (for updates / put / patch)
let mailchimpEmailId = md5(values["unsubscribe-email-address"].toLowerCase());
var postData = {
email_address: "somedude#gmail.com",
status: "subscribed"
};
// Configure headers
let axiosConfig = {
headers: {
'authorization': "Basic " + Buffer.from('randomstring:' + API_KEY).toString('base64'),
'Accept': 'application/json',
'Content-Type': 'application/json'
}
};
try {
let mcResponse = await axios.post('https://us12.api.mailchimp.com/3.0/lists/' + mcListId + '/members', postData, axiosConfig)
console.log("Mailchimp List Response: ", mcResponse);
} catch(err) {
console.log("Mailchimp Error: ", err);
console.log("Mailchimp Error: ", err["response"]["data"]);
}
You can using the method described there: AJAX Mailchimp signup form integration
You will need to use JSONP otherwise you will get a CORS error.
If you use a modern environment (I mean not jQuery), you can achieve this method using a library like qs or queryString to transform your form data to an uri.
Your final url could look something like:
jsonp(`YOURMAILCHIMP.us10.list-manage.com/subscribe/post-json?u=YOURMAILCHIMPU&${queryString.stringify(formData)}`, { param: 'c' }, (err, data) => {
console.log(err);
console.log(data);
});
It's a bit hacky and I guess Mailchimp can remove this from one day to the other as it's not documented, so if you can avoid it, you'd better do.

Post form data with axios in Node.js

I'm testing out the Uber API on Postman, and I'm able to send a request with form data successfully. When I try to translate this request using Node.js and the axios library I get an error.
Here is what my Postman request looks like:
The response I get is: { "error": "invalid_client" }
Here is what I'm doing in Node.js and axios:
var axios = require("axios");
const config = { headers: { 'Content-Type': 'multipart/form-data' } };
axios.post('https://login.uber.com/oauth/v2/token', {
client_id: '***',
client_secret: '***',
grant_type: 'authorization_code',
redirect_uri: 'http://localhost:8080/',
code: '***'
}, config)
.then(function(response) {
console.log(response.data)
})
.catch(function(error) {
console.log(error)
})
When I do this, I get a 400 response.
I added the 'multipart/form-data' header because I filled out the form-data in the Postman request. Without the header I get the same result.
I'm expecting to get the same response I'm getting from Postman, is there something wrong with my config variable in the Node.js script?
Any help would be appreciated!
You might be able to use Content-Type: 'application/x-www-form-urlencoded'. I ran into a similar issue with https://login.microsoftonline.com where it was unable to handle incoming application/json.
var axios = require("axios");
axios({
url: 'https://login.uber.com/oauth/v2/token',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: `client_id=${encodeURIComponent('**')}&client_secret=${encodeURIComponent('**')}&grant_type=authorization_code&redirect_uri=${encodeURIComponent('http://localhost:8080/')}&code=${encodeURIComponent('**')}`
})
.then(function(response) {
console.log(response.data)
})
.catch(function(error) {
console.log(error)
})
You could also use a function to handle the translation to formUrlEncoded like so
const formUrlEncoded = x =>
Object.keys(x).reduce((p, c) => p + `&${c}=${encodeURIComponent(x[c])}`, '')
var axios = require("axios");
axios({
url: 'https://login.uber.com/oauth/v2/token',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: formUrlEncoded({
client_id: '***',
client_secret: '***',
grant_type: 'authorization_code',
redirect_uri: 'http://localhost:8080/',
code: '***'
})
})
.then(function(response) {
console.log(response.data)
})
.catch(function(error) {
console.log(error)
})
Starting with Axios 1.3, you can send multipart/form-data data using FormData:
const axios = require('axios');
const form = new FormData();
form.append('my_field', 'my value');
form.append('my_other_field', 'my second value');
axios.post('http://example.com', form)
FormData is available on Node 17.6.0 (or newer), on older versions you'll have to use a polyfill such as form-data.
If you're using older versions of both Node and Axios, you have to set the Content-Type header yourself as well:
const axios = require('axios');
const FormData = require('form-data');
const form = new FormData();
axios.post('http://example.com', form, { headers: form.getHeaders() })
To send data with Content-Type application/x-www-form-urlencoded, wrap your {} with new URLSearchParams(). Like this snippet:
const axios = require("axios");
axios
.post("https://api.zipwhip.com/user/login", new URLSearchParams({
username: "hello",
password: "byby",
}))
.then((res) => console.log(res.data));
As for 10 June 2017, axios library does not support posting form data in Node.js. Here is the issue on GitHub - https://github.com/mzabriskie/axios/issues/789
We had the similar problem and decided to switch to request library.
This use case is now clearly documented with multiple solutions in the axios docs: https://axios-http.com/docs/urlencoded#form-data
From the error it seems your client_id or client_secret is incorrect. Enable debugging and share the raw request/response (after filtering credentials out).
It is not true! You can post data with axios using nodejs. I have done it. The problem is, if you use PHP on the server side, there is a pitfall you need to be aware of. Axios posts data in JSON format (Content-Type: application/json) PHP's standard $_POST array is not populated when this content type is used. So it will always be empty. In order to get post parameters sent via a json request, you need to use file_get_contents("http://php://input") .
A simple PHP script on the server side would be:
if($_SERVER['REQUEST_METHOD']==='POST' && empty($_POST)) {
$_POST = json_decode(file_get_contents('http://php://input'));
}
Using this method you can avoid the formData dependency. You CAN post data directly from node.js.

Categories