I have a React project that I run with npm start and this code gets 401 Error from the second fetch (the first one is ok). It runs fine returning 200 only with node, like in "node App.js".
So what would I need to do to run my React project getting 200 response? Why is there this difference between npm and node to this request response?
const clientID = <ClientID>
const clientSecret = <ClientSecret>
const encode = Buffer.from(`${clientID}:${clientSecret}`, 'utf8').toString('base64')
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${encode}`,
},
};
fetch("https://auth-nato.auth.us-east-1.amazoncognito.com/oauth2/token?grant_type=client_credentials", requestOptions)
.then(response => { return response.json() })
.then(data => {
const requestOptions2 = {
method: 'POST',
mode: 'no-cors',
headers: { 'Content-Type': 'application/json',
'Authorization': `Bearer ${data.access_token}`
},
body: '{"username":"Ana", "password":"test123","user_id":"ana#email.com"}'
};
fetch('https://j1r07lanr6.execute-api.sa-east-1.amazonaws.com/v1/register', requestOptions2)
.then(response => {console.log(response)});
})
Buffer - is not presented in the browser's javascript.
Instead of
const encode = Buffer.from(`${clientID}:${clientSecret}`, 'utf8').toString('base64')
use just
const encode = btoa(`${clientID}:${clientSecret}`);
Read more about base64 encoding on MDN.
I found out it was a CORS issue that needed to be set correctly on the back-end. My workaround was disabling chrome web security and removing "mode: no-cors".
I've tried adding "Access-Control-Allow-Origin":"http://localhost:3000" to headers but it doesn't work.
Related
I'm trying to stream price data via HTTP (Don't know why they don't use websockets..) and I use axios to make normal REST API requests but I don't know how to handle 'Transfer Encoding': 'chunked' type of requests.
This code just hangs and doesn't produce any error so assume it's working but not able to process the response:
const { data } = await axios.get(`https://stream.example.com`, {headers:
{Authorization: `Bearer ${token}`, 'Content-Type': 'application/octet-
stream'}})
console.log(data) // execution hangs before reaching here
Appreciate your help.
WORKING SOLUTION:
As pointed out from the answer below, we need to add a responseType: stream as an axios option and also add an event listener on the response.
Working code:
const response = await axios.get(`https://stream.example.com`, {
headers: {Authorization: `Bearer ${token}`},
responseType: 'stream'
});
const stream = response.data
stream.on('data', data => {
data = data.toString()
console.log(data)
})
FYI, sending the content-type header for a GET request is meaningless. The content-type header applies to the BODY of the http request and there is no body for a GET request.
With the axios() library, if you want to get direct access to the response stream, you use the responseType option to tell Axios that you want access to the raw response stream:
const response = await axios.get('https://stream.example.com', {
headers: {Authorization: `Bearer ${token}`,
responseType: 'stream'
});
const stream = response.data;
stream.on('data', data => {
console.log(data);
});
stream.on('end', () => {
console.log("stream done");
});
Axios document reference here.
I am using JS axios. I do not understand this error.
error:
Error: Request failed with status code 422
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:62)
This is my code:
const config = {
headers: { Authorization: `Bearer ${localStorage.getItem('id_token')}`,
headers: {
// Overwrite Axios's automatically set Content-Type
'Content-Type': 'application/json'
}
}
};
const bodyParameters = {
password:values.newPassword
};
setIsLoading(true)
//localhost:5000/api/v1/user/updatepassword
Axios.post('http://127.0.0.1:5000/api/v1/user/updatepassword',
bodyParameters,
config
)
And I am testing with fetch in chrome console. and got this error:
SyntaxError: Unexpected Identifier
I think your error is use 2 headers in config object. You can write it like this:
const config = {
headers: {
Authorization: `Bearer ${localStorage.getItem('id_token')}`,
'Content-Type': 'application/json'
}
}
422 status code means that your backend understands your request, but can't process the body (data) you sent.
You can try:
const config = {
method: 'post',
url: 'http://127.0.0.1:5000/api/v1/user/updatepassword',
headers: {
Authorization: `Bearer ${localStorage.getItem('id_token')}`,
'Content-Type': 'application/json'
},
body: {
password:values.newPassword
}
}
axios(config).then(response => console.log(response)).catch(err => console.error(err))
If you get the same error, check your backend gets all the fields it needs.
One more thing you can do: Try making the request on Postman and when it works you can get the axios code for it directly in the code section.
I was trying to monitor my order packages
So there is the package track number.
Maybe it's not Submitting
I need to get the result from the expected page but it seems i'm on the base_url
code:
const fetch = require("node-fetch");
const base_url = "https://www2.correios.com.br/sistemas/rastreamento/";
const data = { acao: "track", objetos: "OD769124717BR", btnPesq: "Buscar" };
fetch(base_url, {
method: "POST",
body: JSON.stringify(data),
headers: {
acceptEncoding: "gzip, deflate, br",
connections: "keep-alive",
},
})
.then((results) => results.text())
.then(console.log);
the source of the form data:
acao=track&objetos=OD729124717BR&btnPesq=Buscar
Have you tried adding a catch to the fetch? If you do this, you will see that it is erroring with the error message "Failed to fetch". I've added this to your existing example so you can try for yourself:
const fetch = require("node-fetch");
const base_url = "https://www2.correios.com.br/sistemas/rastreamento/";
const data = { acao: "track", objetos: "OD769124717BR", btnPesq: "Buscar" };
fetch(base_url, {
method: "POST",
body: JSON.stringify(data),
headers: {
acceptEncoding: "gzip, deflate, br",
connections: "keep-alive",
},
})
.then((results) => results.text())
.then(console.log)
.catch(error => console.error("Error:", error.message));
I would recommend that you do some simple testing using cURL commands within the command line, or use a GUI tool such as Postman or SOAP UI to ensure that you have a valid URL and data parameters when testing this endpoint.
I am running nodeJS and have the following function:
const fetch = require("node-fetch");
async function createCustomer() {
let response = await fetch('https://sampleurl.com/login', {
method: 'POST',
body: 'username=usernameHere&password=passwordHere',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json, text/plain, */*'
}
});
tempVar = await response.json();
console.log(tempVar);
This logs in and authenticates, providing me a successful response.
However if I then try and do the next step, it fails with an unauthorized error.
let response2 = await fetch('https://sampleurl.com/list', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json, text/plain, */*'
}
});
tempVar2 = await response2.json();
console.log(tempVar2);
In python I use requests.Session() and do the initial authorization and then any API call after that just begins with 'session' and it works. For example::
session = requests.Session()
session.post('https://sampleurl.com/login',data={'username':'usernameHere','password':'passwordHere'})
response = session.get('https://sampleurl.com/list').json()
print(response)
This is the functionality I am trying to replicate, but I can't figure out how to store the session.
Any help would be much appreciated.
Edit: Using Express.
Edit2: This is not hitting an API I am running the server for, I am not looking for how to build this feature as the API server, rather just connect to an external API.
I am trying to upload a file from a react front end to a C# backend. I am using drop zone to get the file and then I call an api helper to post the file but I am getting different errors when I try different things. I am unsure exactly what the headers should be and exactly what I should send but I get two distinct errors. If I do not set the content-type I get 415 (Unsupported Media Type) error. If I do specify content type as multipart/form-data I get a 500 internal server error. I get the same error when the content-type is application/json. The url is being past in and I am certain it is correct. I am unsure if the file should be appended as file[0][0] as I have done or as file[0] as it is an array but I believe it should be the first. Any suggestions welcome :) Here is my api post helper code:
export const uploadAdminFile = (file, path, method = 'POST', resource =
config.defaultResource) => {
const url = createUrl(resource, path);
const data = new FormData();
data.append('file', file[0][0]);
data.append('filename', file[0][0].name);
const request = accessToken =>
fetch(
url,
{
method,
mode: 'cors',
withCredentials: true,
processData: false,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json', //'multipart/form-data',
Authorization: `Bearer ${accessToken}`,
},
body: data,
})
.then(res => res.json())
.then(success => console.log('API HELPER: file upload success: ', success)
.catch(err => console.log('API HELPER: error during file upload: ', err)));
return sendRequest(request, resource);
};
Thanks for the help and suggestions, it turned out to be a backend issue but even still I learned a lot in the process. I will post my working code here in case anyone comes across this and finds it useful.
export const uploadAdminFile = (file, path, resource=config.defaultResource) => {
const url = createUrl(resource, path);
const formData = new FormData();
formData.append('file', file[0][0]);
formData.append('filename', file[0][0].name);
const request = accessToken =>
fetch(url,
{
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: formData,
});
return sendRequest(request, resource);
};
As mentioned, the file name does not need to be sent separately and count be omitted. I am indexing the file this way because I get it from dropzone as an array and I only want a single file (the first one in the array). I hope this helps someone else out and here is a link to the mdn fetch docs (good information) and a good article on using fetch and formData.