I have used Postman to explore an API for Samsung's SmartThings. I have that working as expected. But when I take that information and try to implement it in node with Axios the data returned looks like it is compressed or some other blob. Here is the code I am trying to use to get the response:
const axios = require("axios");
function main() {
const st_api = axios.create();
st_api
.get("https://api.smartthings.com/v1/locations/", {
headers: {
get: {
Accept: "application/vnd.smartthings+json",
},
Authorization: process.env.my_home_token,
},
responseType: "json",
responseEncoding: "utf8",
decompress: true,
})
.then(function (res) {
console.log("Status: ", res.status);
console.log("Data: ", res.data);
})
.catch(function (err) {
console.log("Error: ", err);
});
}
main();
And the console log returned is:
Status: 200
Data: �$ͱ�0��W1wn��-H�����d���6KK��»[�v�/���������BC���BXn���%�ek3��j��&�� m�x�M��i�i1 ��פ��8�`�����4�r_����d�ޤ�A�Z��K�K��UV�rk²�<\�_㿻���wA��
I have tried inserting gzip to decompress it or other header information but nothing changes. I am expecting some json returned (or at least something human readable would be a start). I believe I distilled my simple (I hope) api call to a brief test and nothing I try has changed the data being returned.
This is a bug in Axios. Downgrade your Axios version to 1.1.3 or lower, and don't upgrade until 1.3.0 is released. Ref: https://github.com/axios/axios/pull/5300, https://github.com/axios/axios/pull/5306
Related
I have used Postman to explore an API for Samsung's SmartThings. I have that working as expected. But when I take that information and try to implement it in node with Axios the data returned looks like it is compressed or some other blob. Here is the code I am trying to use to get the response:
const axios = require("axios");
function main() {
const st_api = axios.create();
st_api
.get("https://api.smartthings.com/v1/locations/", {
headers: {
get: {
Accept: "application/vnd.smartthings+json",
},
Authorization: process.env.my_home_token,
},
responseType: "json",
responseEncoding: "utf8",
decompress: true,
})
.then(function (res) {
console.log("Status: ", res.status);
console.log("Data: ", res.data);
})
.catch(function (err) {
console.log("Error: ", err);
});
}
main();
And the console log returned is:
Status: 200
Data: �$ͱ�0��W1wn��-H�����d���6KK��»[�v�/���������BC���BXn���%�ek3��j��&�� m�x�M��i�i1 ��פ��8�`�����4�r_����d�ޤ�A�Z��K�K��UV�rk²�<\�_㿻���wA��
I have tried inserting gzip to decompress it or other header information but nothing changes. I am expecting some json returned (or at least something human readable would be a start). I believe I distilled my simple (I hope) api call to a brief test and nothing I try has changed the data being returned.
This is a bug in Axios. Downgrade your Axios version to 1.1.3 or lower, and don't upgrade until 1.3.0 is released. Ref: https://github.com/axios/axios/pull/5300, https://github.com/axios/axios/pull/5306
I am attempting to use a streaming strategy to send data in chunks to the browser. However, when the data is read it does not send them in chunks from the code written to stream the results. It reads and sends the first batch and then gives a message that there are some more items left. Why isn't the rest of the data streamed? I thought was how Observables work, to read the data in chunks in the next callback. Here are how the results are displayed, but with the ... more items, shown below
[
...,
{
productCode: 1829222,
productName: 'Twizzlers'
} ,
... 141 more items
]
Here is the code that tries to stream the data:
const fetch = (url, payload) =>{
try{
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
};
const request = new Request(url, requestOptions);
const data$ = fromFetch(request).pipe(
switchMap(response => {
if (response.ok) {
return response.json();
} else {
return of({ error: true, message: `Error ${ response.status }` });
}
}),
catchError(err => {
console.error(err);
return of({ error: true, message: err.message })
})
);
data$.subscribe({
next: result => console.log(result),
complete: () => console.log('done')
});
}catch(e){
console.error(e)
}
}
I am attempting to use a streaming strategy to send data in chunks to the browser.
Data is sent to the browser in chunks. When the server sends data to the browser, the server is sending it in "chunks" and the browser is storing it in a buffer. You are decoding that buffer to something useable when you run response.json().
For further reading on TCP connections (How GET, POST, etc) work under the hood, I suggest reading the "Bulding blocks of TCP" chapter in the book "High Performance Browser Networking" https://hpbn.co/building-blocks-of-tcp/
Your code works well with standard GET request for some dummy json. I can see the response well and I'm not seeing the error you are seeing
https://stackblitz.com/edit/rxjs-xwyctu?file=index.ts
If you are actually trying to "stream" data to the browser, you can look into Server Sent Events (SSE) https://hpbn.co/server-sent-events-sse/. This is how you can establish a long running GET request to stream data from the server to the client.
You can see an example here: https://github.com/Fallenstedt/server-sent-events-example
Whenever I go to any API route in my Next.js app in production it returns a 500 "Internal Server Error" but in development, all of them work completely fine and show/return what I expect them to.
I am deploying with an AWS Ec2 instance.
the code is available here: https://github.com/123om123/NFT-Marketplace
These are all my API routes.
The [...auth0].js creates the following routes:
/api/auth/login,
/api/auth/logout,
/api/auth/callback, and
/api/auth/me
If I try to access the "find_account" API route like the following:
let findAccount = async function () {
await fetch("/api/find_account", {
method: "POST",
body: JSON.stringify({
DBUrl: DBUrl,
user_id: user.sub,
}),
})
.then(async (response) => {
await response.json().then((result) => {
accountData = result;
if (accountData.data.allAccounts.nodes[0].addresses !== null) {
setAddressList(accountData.data.allAccounts.nodes[0].addresses[0].split(","));
}
});
})
.catch((err) => {
return err;
});
};
which handles requests like the following:
export default function handler(req, res) {
req.body = JSON.parse(req.body);
fetch(req.body.DBUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `query MyQuery {
allAccounts(condition: {userId:"${req.body.user_id}"}) {
nodes {
addresses
}
}
}`,
}),
})
.then((response) => {
response.json().then((response) => {
res.status(200).send(response);
});
})
.catch((err) => {
res.status(500).send(err);
});
}
it works fine and returns the response from the graphql API in development, but in production it shows the above error.
The problem seems to be that the API routes aren't even created and are therefore inaccessible. All the API routes worked a few weeks ago, but now they seem to have stopped working.
Check out this answer, it helped me solve a bug similar to yours. In my case when vercel was deploying my PR branch I was getting a 500 Internal Error. Once I merge the PR into main and vercel does a fresh deployment, I was now getting a 504 gateway error. The answer below helped me find out why.
https://stackoverflow.com/a/68774331/12775824
Actually am kinda disappointed as I tried many things and checked out many articles but non worked out for me.
function demo() {
console.log("Booooooooooooommmmmmmmmmm");
tokenV = document.getElementById("tokenString").value;
var urlF = "https://***********.com/connect/api.php?action=2&token="+tokenV;
const myHeaders = new Headers();
const myRequest = new Request(urlF, {
method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default',
});
fetch(myRequest)
.then(response => response.json())
.then(data => console.log(data));
}
I have already whitlist the domain inside my config file, am using phonegap CL latest version. I'm trying to connect to an api which will out put json.encode data if token were right.
Error output:
(index):50 Fetch failed loading: GET https://*******.com/connect/api.php.............
Another way I tried using cordova fetch plugin still failed:
function demo() {
console.log("Booooooooooooommmmmmmmmmm");
tokenV = document.getElementById("tokenString").value;
var urlF = "https://*********.com/api.php?action=2&token="+tokenV;
console.log("nowww1");
cordovaFetch(urlF, {
method : 'GET',
headers: {
'User-Agent': 'CordovaFetch 1.0.0'
},
})
.then(function(response) {
return response.json();
}).then(function(json) {
console.log('parsed json', json);
}).catch(function(ex) {
console.log('parsing failed', ex);
});
}
Error out put:
Error: exec proxy not found for :: FetchPlugin :: fetch (index):118 parsing failed TypeError: Network request failed
I can change the out put as I want but show me away to get the data from an external server???
Thank you
I am working on a project using electron and reactjs. I am therefore using electron-fetch to fetch data from an API using JSON to send and return JSON response.
In the network console I can see I get the expected result (I also use test client (Insomnia) and confirm I get a JSON response which is as follows:
{
"result": 0,
"message": null,
"data": [
{
"MonitorId": 2,
"LogName": "Test",
"LogPath": "/root/test"
}
]
}
However, in the electron app, in the network tab response I can see the JSON object as above but I get the following error shown in the console
SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse ()
at index.es.js:234
When I print out the response.body I see [object object] instead of the actual JSON.
Below is my fetch request
try
{
fetch(url, {
method: 'post',
headers: {
'Content-Type': 'application/json',
'authorisation_token': authorisation
},
mode: 'cors',
body: JSON.stringify(postArray)
}).then(function (response) {
if (response.status !== 200)
{
console.log("Something went wrong. Status Code: " + response.status);
reject(response);
return;
}
console.log(response);
response.json().then(function (data) {
resolve(data);
}).catch(function (err) {
console.error("Caught Error: " + err);
reject(err);
});
});
}
catch (err)
{
console.error(err);
}
I've recently used normal fetch in the same way and not had a problem, so not sure if this is something specific to electron-fetch or whether I'm missing something here.
As mentioned in the comments, I had a look at a project that uses Electron and React (Insomnia.Rest) and found when they do a request they don't seem to use electron-fetch just normal fetch but they do window.fetch() and when I tried that it seems to work as expected