I've got this cURL request working perfectly on remote interface just as it should
curl -XGET "https://server.host:8080/peregrine" -d '{"exchanges":["kucoin", "kraken"],"volume":10}' -k
I'm trying to build a little frontend app with Vue.js and need the above converted to an Axios get request.
I've been trying the following so far:
axios({
method: 'get',
url: 'https://server.host/peregrine',
data: {"exchanges":["kucoin", "kraken"],"volume":10}
});
putting params instead of data makes it a URL and remote server says that it received no data.
What am I doing wrong? Thanks.
Likely the problem could be that using GET you cannot pass data like you are doing. You have to pass them as query parameter.
Try to change your call with:
axios.get('https://server.host/peregrine', {
params: {"exchanges":["kucoin", "kraken"],"volume":10}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// always executed
});
GET requests should not have request bodies.
CURL will allow you to make a GET request with one, but XMLHttpRequest and fetch (the HTTP APIs in browsers which axios wraps) will not.
Make a POST request instead. You might need to change the server-side code to support this.
Thanks for your replies!
Indeed there's no way to send data body with axios.get()
We ended up tuning the server side to accept normal generic GET requests. Thanks again to everyone who answered!
Related
I've been trying to send a GET request to an api to fetch data using Axios but always get a response object with status, headers, config, agents etc and response.data is always empty.
For example, the following code returns me an Axios response object with the hasBody set to true and data being empty.
axios.get(`https://fantasy.premierleague.com/api/leagues-classic/12000/standings/`).then(response => {console.log(response);
console.log(response.data);});
However, when I switched over to using Request library which has been deprecated, I am able to get the response body. For example, the following code works:
request(`https://fantasy.premierleague.com/api/leagues-classic/12000/standings/`, { json: true }, (err, res, body) => {
if (err) { return console.log(err); }
console.log(body);
});
Can someone tell me what am I doing wrong and how can I get the response body using axios? I'm a beginner and have spent hours trying to figure out so I would really appreciate any form of help.
It's not an axios library issue. From what I can tell, the server does't like the user-agents starting with "axios/". Specifying some user agent gives you the expected result:
const axios = require("axios");
axios.get(`https://fantasy.premierleague.com/api/leagues-classic/12000/standings`, {
headers: {
'user-agent': 'not axios',
}
}).then(response => {
console.log(response.data);
});
As for why the requests library works but axios does not: axios is setting the user-agent header to something like axios/0.21.1 or whatever version you have. requests on the other side, leaves the user-agent header unset. It's the server right to handle the request as he pleases.
I have verified the response from this URL https://fantasy.premierleague.com/api/leagues-classic/12000/standings/ - there is no data property in the response
Try like below to read the values:
It seem like your URL at https://fantasy.premierleague.com/api/leagues-classic/12000/standings/ had invalid response body.
I have a custom Api which I secured with Azure AD like the following tutorial:
https://learn.microsoft.com/en-us/sharepoint/dev/spfx/use-aadhttpclient
Thats working great.
now I have the following Code to make a GET request to my custom API (working):
this.context.aadHttpClientFactory
.getClient('MY_API_URL')
.then((client: AadHttpClient) => {
console.log(AadHttpClient.configurations.v1);
return client
.get(
`MY_API_URL/SOME_ROUTE`,
AadHttpClient.configurations.v1
);
})
.then(response => {
var res= response.json();
return res;
}).then( (res: any[]) => {
...
HERE I WOULD LIKE TO GET MY TOKEN
});
So this is working how I expect it to work.
But the aadHttpClientFactory only supports GET and POST requests
Now my Idea was to just make some PUT/DELETE requests with jQuery and use the Bearer token I got above (tested with postman and its working).
But then I realised, that I won't get the token that easy.
When I console.log(AadHttpClient.configurations.v1) I only get this:
Sure I could just change my API to use POST instead of PUT/DELETE but that would be pretty ugly
Does anyone has an Idea on how I could get the token as a String to do custom requests with it?
AadHttpClient supports the fetch(url, configuration, options) method, where options can include all of the request configuration options supported by the Fetch API.
So, to make a DELETE request, you would do something along the lines of:
client
.get(
`MY_API_URL/SOME_ROUTE`,
AadHttpClient.configurations.v1,
{
method: 'DELETE'
}
);
I solved it now.
Maybe my answer will help someone later.
according to philippe Signoret's answer the is the fetch() function.
I had to use it like following:
this.context.aadHttpClientFactory
.getClient(api_url)
.then((client: AadHttpClient) => {
return client
.fetch(
MY_URL,
AadHttpClient.configurations.v1,
{
method: METHOD, //put/DELETE etc.
headers: [
["Content-Type", "application/json"]
],
body: JSON.stringify({
YOUR REQUEST BODY
})
}
)
});
I want to update a document in Mongo, but when I send an Axios POST request to the server with params for the updates I receive nothing but a blank object on the server side - I'm using Node.js with an Express server (MERN stack).
I have tried the qs library module and Node's querystring module. I tried including headers with
'Content-Type': 'application/x-www-form-urlencoded' and 'application/json'.
My Axios POST request:
const A = 1;
const B = 2;
const data = { A, B };
console.log(qs.stringify(data)); // A=1&B=2
axios.post(url('upVote'), qs.stringify(data));
The server route:
app.post('/upVote', async (req, res) => {
console.log(req.params); // {}
await DB.updateVote(ID, collection, voteCount);
res.end();
});
The headers as shown by Chrome's DevTools.
... Also, all my axios.get() requests work fine and grab data from Mongo and send it back to my app properly, and the url/endpoints match.
There are a couple of ways to send data to the server with axios.
I see the confusion with the documentation in axios, I have not seen this usage before and it does seem to be broken upon looking at the request logs and object.
1) axios.post receives body of the request as a second parameter. So if you want to pass parameters to axios, you should do something like this:
const B = 2;
const data = { A: 1, B: 1 };
axios.post(url('upVote'), {}, { params: data });
Note that axios will handle stringification on it's own and that the third parameter is a config object.
On the server the params will be available at request.query
2) If you want to stringify the parameters yourself, then you should append them into your URL like so
axios.post(`url('upVote')?${qs.stringify(data)}`);
Same here, data on the server will be under request.query
3) It's generally better to use the body of the post request to transfer large data payloads for convenience. You should also consider what your caching strategies are and if they rely on request url without the consideration of request body it may be a concern.
axios.post(url('upVote'), data);
In this case data on the server will be under request.body
UPD: Originally forgot to mention that you will need a body-parser middleware to access request.body.
4) You can use axios without method shorthands which may be useful for some people
axios({
method: 'POST',
url: url('upVote'),
params: data
})
This is identical to the example in 1.
And all of them return a Promise which you can .then().catch() or await.
I think you want .body instead of .params.As you are sending data in body by post using axios. You are printing params which will print nothing for this url/api .
Try
console.log(req.body) // instead of req.params
If this did not work then please show us your react code.
Moreover
In react you have to add .then() after axios else it will say unhanded promise
To get params on server side you have to make some changes
In axios (react)
axios.post(url('upVote/param'), qs.stringify(data));
In server
app.post('/upVote/:params', async (req, res) => {
console.log(req.params)
.....
})
I think you are calling res.end(). I think it should be res.send(...)
This answer should help: https://stackoverflow.com/a/29555444/1971378
My goal is to fetch the status data from a UBNT radio (https://www.ubnt.com/) using an HTTP request. The web interface url is formatted as http://192.168.0.120/status.cgi. Making the request requires a authentication cookie. Using the cookie copied from the existing web interface I am able to successfully retrieve the data.
This is my current code using the Meteor framework.
radioHost = "http://192.168.0.120";
HTTP.call("POST", radioHost + "/login.cgi",
{
headers: {
"Content-Type": "multipart/form-data"
},
data: {
username: "ubnt",
password: "ubnt"
}
}, (err, res) = > {
if(err) return console.log(err);
var cookie = res.headers["set-cookie"][0];
HTTP.call("GET", radioHost + "/status.cgi", {
headers: {
cookie
}
}, (err, res) = > {
if(err) return console.log("Error");
console.log(res);
})
})
The above code achieves both request successfully. However the server is responding to the first with a faulty token ("set-cookie" string). Using the cookie from the existing web framework the response is correct.
Here is a library written in Python that I believe does a similar thing. https://github.com/zmousm/ubnt-nagios-plugins
I believe my problem lies within the HTTP request and the web api not cooperating with the username and password.
Thanks in advance for any help.
A direct POST request to a url is not a recommended way. When you open a browser you just don't directly login. You fetch the page and then submit/login
Not simulating this behavior may impact certain sites depending on how the server works.
So if always want to look at the simulating like a real user/browser would do, make a GET request first and then the POST.
Also capture any cookies from the first GET request and then pass the same on to the next one
I'm just following tutorials and figuring out how to handle get requests in NodeJS.
Here are snippets of my code:
NodeJS:
router.get('/test', function(request, response, next) {
console.log("Received Get Request");
response.jsonp({
data: 'test'
});
});
Angular:
$http.get("http://localhost:3000/test").
success(function(response) {
alert("OK");
}).
error(function(response) {
alert("FAIL");
});
If I try to access the link directly # localhost:3000/test, I'm able to receive the JSON message correctly. But when I use angularJS $http call, the request always fails and I'll find this error in the network inspector (Response)
SyntaxError:JSON.parse:unexpected end of data at line 1 column 1 of
the JSON data
The reason for that is because the response is empty but the response code is 200 in both cases.
I've tried searching for hours but maybe someone can enlighten me on this?
you could try and send
res.send('test')
and then on your http request you can use 'then'
$http.get("http://localhost:3000/test").then(function(res) {
console.log(res);
})
unlike success, then will give you a complete object (with 'test' - string as res.data)
success will bring you only the data;
then will bring you the whole object (with the status and such)..
now about that jsonp .. it's used to override a json response. you could simply use 'res.json({data: 'test'})' and it should also work for you..
hope it helps
You're using jsonp in node, which you probably don't need to. This adds extra characters to the response and so the JSON parser fails to parse (that's what the error is telling you, the JSON is malformed)
Try changing the server to look like
response.json({
data: 'test'
});
If you look in the Network pane of the developer tools, you should be able to see the raw response. It should look something like:
{"data" : "test"}