Request JS Uri requesting incorrectly - javascript

I am trying to POST to a server using Request JS. I am having issues with parts of the path.
return await request.get({
method: 'POST',
uri: `${domain}/info/test/`,
body: bodyAsString,
headers: {
Authorization: `bearer ${token}`,
},
}).pipe(res);
This api has two ways to hit it: /info/test as a POST and /info/test/:GUID as a GET. For some reason, when I hit the API with Request it complains that 'test' is not a valid GUID like I am one level too low on the path. I can hit it in Postman just fine.

you should use request.post instead of request.get

Related

Axios ignores Content-Type 'application/json' with GET HTTP Method

I'm trying to fetch data from a Node.JS API via Axios. The API only accepts requests with content-type "application/json" and GET HTTP Method. If the content-type is not "application/json", an error message will be sent back.
I've tested the API with Postman and other HTTP libraries and everything works perfectly fine.
However, when I try to make a request via Axios:
export const getPrivateInstance = axios.create({
baseURL: API_URL,
timeout: 25000,
withCredentials: true
})
getPrivateInstance({
method: 'get',
url: "/getData",
data: JSON.stringify({
projectId: projectID
}),
headers: {
"Content-Type": 'application/json',
}
})
the Content-Type is ignored when specifying GET as the HTTP Method. However, if I change the http method to POST in the axios config and API, it works. But with GET, the content-type is ignored by Axios.
How can one make a GET Request where the content-type is not ignored by Axios?

Downloading large files with axios

I am currently downloading large files to my client code using the axios lib. Files are around 600MB. But during the download process the page crashes, like it runs out of memory or similar.
I need to hold the file in the memmory because the content is encrypted and I need to decrypt it before passing it to the user.
I use the REST GET Http request like this:
axios.get(url, {
headers: {
"Authorization": authHeader().Authorization,
"Accept" : "application/octet-stream, application/json, text/plain, */*"
}, responseType: 'arraybuffer'
})
.then(function(response) {
console.log(response);
Are there any common workaround around the problem. So far I wasn't able to find any.
Open the url in the new tab on the client side using
window.open(url)
Let the browser handle the document automatically,
If you want to decrypt the data, please try to decrypt on server side since you'll be giving out decryption key on the client side, which can have security issues.
Do you actually need to do it with axios? There is the Fetch API, which can serve the purpose. Here's how I do it for files in the same size range as yours (media files and ZIPs of up to 1 GB):
fetch(url, {
mode: 'no-cors', // to allow any accessible resource
method: 'GET',
})
.then((response) => {
console.debug('LOAD_FROM_URL::response', response);
//NOTE: response URL is possibly redirected
See https://github.com/suterma/replayer-pwa/blob/main/src/store/actions.ts for more context.
It's working flawless so far for me.
Can you please give a try by setting maxContentLength and maxBodyLength to Infinity in the axios call.
axios.get(url, {
headers: {
"Authorization": authHeader().Authorization,
"Accept" : "application/octet-stream, application/json, text/plain, */*"
},
responseType: 'arraybuffer',
maxContentLength: Infinity,
maxBodyLength: Infinity
})
.then(function(response) {
console.log(response);
}
You can also have a look into this axios issue forum for the same.
HTTP Protocol: Range Parameter
Use the 'Range' header for getting big files part by part.
Example Curl HTTP Request : https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
curl http://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023"
Example JS
axios.get(url, {
headers: {
"Authorization": authHeader().Authorization,
"Accept" : "application/octet-stream, application/json, text/plain, */*",
//--------------------------|
"Range" : "bytes=0-1023" // <------ ADD HERE
//--------------------------|
},
responseType: 'arraybuffer'
}).then(function(response) {
console.log(response);
}
You need to revisit the design of your frontend. Either its ReactJs or Angular or plain JS, just Offload such large downloads as well as other long running scritps to a concept of JavaScript Web Workers. This is latest way to offloading javascript tasks to the background so the page responsiveness remains intact.
Otherwise JavaScript is single threaded so there is no way to bypass the issue. WebWorkers are only thing to make exceptions here
It is as of today now supported on all latest browsers.
More on this: link

API call (fetch) with user token through Javascript (React.js)

how are you guys doing??
I'm trying to fetch data (in React with JS) from a website X (that has cors-enabled) but need first to get a user token from a website Y and I don't know how to figure that out. Somehow I think that I have to get the user token from Y, save it in a variable and add it as a header on the other call but I'm kinda lost with the GET/POST methods.
By now what I have is this but somehow doesn't work, I think I'm not sending properly the head or making the actual calls correctly:
getToken(){
const url = 'websiteOfTheToken';
const response = await fetch(url);
const data = await response.json();
this.setState({
userToken: data.image
});
}
And:
getData(){
const response = await fetch('websiteOfTheData', {
method: 'POST',
mode: 'no-cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'accept': 'application/json',
'Content-Type': 'application/json'
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: JSON.stringify({
title: '' // I don't know what is this doing
})
}).catch( error => {
console.log('Error fetching and parsing data ', error)
});
this.setState({
data: response.json()
});
}
Thank you in advance!!
A few things I want to say / ask about:
Typically you get the token after a successfull login, so a standard request for a token would be a post request with the user data.
An await in javascript works only inside async functions, read about it.
The most common practice for handling api responses (Promise) is to use then-catch blocks, read about it.
A typical JWT header you need to attach to your requests looks like this: "Authorization": "Bearer theactualtoken1234".
The body of the fetch post request is the actual data you're sending to the server. So its contents are totally arbitrary - I also don't have an idea what this "title": "" is doing...

Postman request works but not axios CORS

In a bit of a pickle at the moment , I could do a postman request like that and I get my data response back :
URL : https://hiddenurlforexample.com
Authorization : Bearer XXXXXXXX-XXXX-XXXX-XXXX
When I do it on Axios on my website though I get a 401 CORS error. Any idea what the difference is ? This is how my axios request looks like :
axios
.request({
url: 'test/url',
method: 'get',
baseURL: 'https://hiddenurlforexample.com',
headers: {
"Access-Control-Allow-Origin" : "*",
"Content-type": "Application/json",
"Authorization": "Bearer XXXXXXXX-XXXX-XXXX-XXXX"
}
})
.then(response => {
console.log(response.data)
})
.catch(function (error) {
console.log(error)
})
I am a Frontend Developer, I have been told that there was nothing to do in the backend .
What Chris G said, and next to that Postman ignores the CORS validation because it is a dev tool.
Your backend server should return the correct CORS headers. While developing you could go with a wildcard for the CORS headers but it's highly recommended to add the specific domain you're calling the backend from (i.e. the domain of your website).
Also note that the CORS headers are returned via an OPTIONS call, again, your backend should support that. What backend are you running?

POST working with Postman but not via fetch in JavaScript

The post request to the Django Rest API framework works via Postman when the appropriate parameters are filled in the 'body' section. But the same does not work with the following JavaScript code:
var data = {emp_id:50,emp_name:'test',password:'pass123'};
fetch('http://127.0.0.1:8000/signup/',{
method:"POST",
body: JSON.stringify(data),
mode:"no-cors",
headers: {
"Content-Type": "application/json",
// "Content-Type": "application/x-www-form-urlencoded",
},
})
.then(response => response.json());
The following is the def that handles the POST request in the views.py of the REST-API:
#api_view(['GET', 'POST', ])
def signup(request):
serializer = employeeSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I'm new to this, can anyone tell me why the JavaScript code won't work?
EDIT:
The error which the browser console shows is:
POST http://127.0.0.1:8000/signup/ 415 (Unsupported Media Type)
The issue is that by using no-cors mode you constrain yourself to using simple requests, which in turn cannot have content-type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain. In fact, if you look at the headers sent by the browser with your request, you'll see that the content type changes from application/json to text/plain - hence the error.
To fix your issue: remove no-cors mode and add cors headers to responses in your django app. You can use django-cors-headers for that.
Also, you have no issues with postman because it does not care about same-origin policy.
Try change headers to
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
The accept header is used by to determine what format to sent the data back to the client in the response, guess it might be needed
I found the solution here : https://learning.postman.com/docs/sending-requests/generate-code-snippets/#generating-code-snippets-in-postman
with postman you can see the code of headers sent on the request on many languages (Node Axios, javascript fetch ...), then just copy paste the headers and all the data sent by postman to your app

Categories