Reading data from res.end() - json

I'm sending a simple data back from the server to the client.
app.post('/user', function (req, res) {
var userName = "John";
res.end(JSON.stringify({"error":"", "user": userName}));
});
$.ajax({
type: "POST",
...
contentType : 'application/json',
dataType: "json"
})
.done(function(data) {
// send join message
var resData = JSON.parse(data);
alert("hello"); // this doesn't show up
});
});
});
But in the browser console, I get this error - "Uncaught SyntaxError: Unexpected token o".
If I do JSON.stringify and JSON.parse on the content, it works fine.
alert(JSON.parse (JSON.stringify({"error":"", "user": userName})).user);
And also, .done works fine without a data payload from the server i.e. the alert("hello") works.
So, I'm guessing something fishy is happening while sending data within res.end(). Please help.
While at it, it would be nice if you can also tell me how to do the same using res.json() and which one is preferable.

The problem here is that you set dataType: 'json' in your jQuery request. This causes the response from the server to be automatically parsed as JSON, so it will return the object rather than the raw server response.

Related

Requesting access token to Zoom API via Oauth - error 'missing grant type'

I'm trying to receive an access token from the Zoom api via Oauth. No matter what form I try and send the body as, 'Content-Type': 'application/json' or Content-Type:application/x-www-form-urlencoded, it always errors to { reason: 'Missing grant type', error: 'invalid_request' }.
var options = {
method: "POST",
url: "https://zoom.us/oauth/token",
body: JSON.stringify({
grant_type: "authorization_code",
code: process.env.AUTH_CODE,
}),
redirect_uri: "https://zoom.us",
};
var header = {
headers: {
Authorization:
"Basic " +
Buffer.from(process.env.ID + ":" + process.env.SECRET).toString("base64"),
},
"Content-Type": "application/json",
};
var tokCall = () =>
axios
.post("https://zoom.us/oauth/token", options, header)
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error.response);
});
tokCall();
I'm fairly certain the answer lies in either the data type in which Oauth is receiving the data, or where/if it's receiving the body at all. Any suggestions would be gratefully received.
The error is being thrown because you're sending the data as the body of the post request when the Request Access Token Zoom API is expecting to find them as query parameters which you might know as query strings.
Reference
https://marketplace.zoom.us/docs/guides/auth/oauth#local-test
Image of page from link to highlight the use of query parameters and content-type requirement for API call
Change
var options = {
method: "POST",
url: "https://zoom.us/oauth/token",
body: JSON.stringify({
grant_type: "authorization_code",
code: process.env.AUTH_CODE,
}),
redirect_uri: "https://zoom.us",
};
to
var options = {
method: "POST",
url: "https://zoom.us/oauth/token",
params: {
grant_type: "authorization_code",
code: process.env.AUTH_CODE,
redirect_uri: "<must match redirect uri used during the app setup on zoom>"
},
};
The Content-Type header should be set to application/x-www-form-urlencoded as this is a requirement of the zoom API itself.
BTW, axios requires you to name the body field/object of your request as data and also there's no need for JSON.stringify() method since axios does that for you under-the-hood
Though it's a late answer, I'd like to share it since it took me some time to complete this using Axios.
So to make Zoom authorization, you need to do:
Base64 encode the secret and client id
const base64EncodedBody =
Buffer.from(`${ZOOM_CLIENT_ID}:${ZOOM_CLIENT_SECRET}`).toString('base64');
URI encode the grant_type, code and redirect_uri
const data =
encodeURI(`grant_type=authorization_code&code=${code}&redirect_uri=${redirectUri}`);
Send the request
const response = await axios.post('https://zoom.us/oauth/token', data, {
headers: {
Authorization: `Basic ${base64EncodedBody}`,
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(data),
},
});

Ajax requesting an API for data on a project

So I am busy with a private coding project right now, but can't seem to get my code to work properly.
I want to in essence, get data from my API and display it on to my HTML page, the data type is set to "jsonp" because of CORS errors( this was the only way I could debug it ), anyone have an idea of how I can get this to return usable data for my project?
function fetch(){
"use strict";var url = "https://api.pandascore.co/lol/champions?token=*my_unique_token*";
$.ajax({
url: url,
type: "GET",
crossDomain: true,
dataType: 'jsonp',
contentType: "application/json; charset=utf-8",
beforeSend: function(xhr){
xhr.setRequestHeader('Access-Control-Allow-Origin','*');
},
success: function(data){
console.log(data);
},
done: function(data){
console.log(data);
},
error: function(error){
console.log(error);
}
});
}
Edit:
This is a parsing problem, I cant get the code to log the success, I can see a response but its for my error log, but it doesn't show the success log, so the data is unusable.
Why not try the vanilla fetch method?
const url = 'https://api.pandascore.co/lol/champions?token=my_unique_token';
fetch(url)
.then(response => response.json())
.then(data => console.log(data))
This code should handle parsing JSON data you receive from pandascore. Fetch is not available in IE11, but there should be some polyfills lying around on the web.

How to get a value from returned JSON in HTML?

My client side looks like this:
filename="random_filename.docx"
var response = await fetch("https://backend.wl.r.appspot.com/scriptstuff", {
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ file: filename })
});
var data = response.json();
console.log(data);
and my backend return looks like this
response = jsonify({'prediction': str(prob)})
response.headers['Access-Control-Allow-Origin'] = '*'
return response, 200
I receive a promise with the value of 'prediction', but I'm not sure how to access that or why the current code isn't working.
EDIT: adding await before response.json() works
You can execute a function upon a promise being fulfilled by appending a .then() to the fetch request. If you're already receiving the JSON object then the values can be accessed by data.some_key.
I'm not an expert but first store str(prob) into a variable and then create an object with it. I think jsonify() takes things very literally.

Is it possible to combine a GET and POST in Javascript?

I have javascript code that should login (ie send some information to the server) and then receive a reply JSON message. I know this is doable by first doing a post, and then in the asynchronous response, when it completes, do a get. This would require two callback functions and two messages.
I was just wondering whether there is any way to do a get and send JSON as part of the query, so that there is just a single request/response rather than two.
Here is a sample post I wrote:
function post(url, payload, callback) {
payload = JSON.stringify(payload);
var http = new XMLHttpRequest();
http.open("POST", location.pathname + url, true);
http.setRequestHeader("Content-type", "application/json");
http.onreadystatechange = function () {
if (http.readyState === 4 && http.status !== 200) {
callback(false, http.response);
} else if (http.readyState === 4 && http.status === 200) {
callback(true, http.response);
}
return;
};
http.send(payload);
}
If I want to get back JSON, what do I do?
Is it as simple as changing POST to GET and looking at:
http.responseText upon the return?
If you are doing any login functionality you should always use the HTTP POST method.
You could use AJAX (W3schools documentation about AJAX ) to handle sending your login form over POST and then handle the response in the same code block. bellow is an example.
$('#login-form').submit(function(e) {
e.preventDefault(); // Prevents the page from refreshing
// serializes the form data with id login-form
var formData = $(this).serialize();
$.ajax({
type: 'POST',
data: formData,
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
url: $(this).attr('action'),
//if your server sends a status OK message handle the response
//data will be the JSON response from the server
success: function(result,status,xhr) {
var jsonRes = JSON.parse(result); // parse the JSON object
console.log(jsonRes);
},
//if there was an error with your request the server will send
// an error response code and it is handled here
error: function(xhr,status,error) {
console.log(error);
}
});

Angular JS issues sending JSON with $ http

I am having issue sending post json data with angular, from PHP I need to access $_POST['action']
This works
$http({
method: 'POST',
url: ajaxurl,
data: "action=get_employer_jobs",
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function (data) {
console.log(data);
$scope.jobs = data;
});
This does not work
app.controller('MainController', ['$scope', '$http', function ($scope, $http) {
console.log('MainController Running');
$http({
method: 'POST',
url: ajaxurl,
data: JSON.stringify({action:"get_employer_jobs"}),
headers: {'Content-Type': 'application/json'}
}).success(function (data) {
console.log(data);
$scope.jobs = data;
});
}]);
You need to process your json on the server side differently.
in PHP, I do it like this:
$_REQUEST = json_decode(file_get_contents("php://input"));
The way Angular sends POST data as json strings, you need to take the whole request string, parse it, then you can use it. It won't automatically be in $_POST or $_REQUEST as a nice array until you do this parsing.
I´d the same problem, it looks like PHP doesn´t fill the $_POST array when it´s passed by the $http service.
Instead of using $_POST, try to parse directly the php://input.
php
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
var_dump($request)
Then you can access using the object notation $request->my_var