Next.js - axios/fetch requests pending when sending body with long content - reactjs

I am trying to send a POST request with body that contains one key with file base64 content.
The problem is that I never get a response. When I check the "Network" tab in Dev Tools, I see that the request is stuck on "pending". When I console.log the variable that contains the base64, I see that it's just 256kb. It happens both with fetch or axios.
This is how I sent the request:
const response = await axios.post(
"/api/newroute",
{
fileName,
fileBase64
},
{
// maxContentLength: Infinity, // Tried that
// maxBodyLength: Infinity, // Tried that
}
);
console.log(response); // never happens
I am not sure whether it is a backend issue or a frontend one (this is a route from next.js).
I also tried to send it as FormData but that didn't help.
Do you have any idea what could have caused this?

Related

axios cannot get only response of base64 but can get the others data

First, I sent an image path from react to Django by using the axios of POST method.
Next, I edited the image in Django, and returned edited images that were converted into base64 to react.
like this.
/* this is view.py in Django */
class SquareCognitionSet(viewsets.ViewSet):
#action(methods=['POST'], detail=False, name='Edit image')
def show(self, request):
input = request.data['input']
edited_image = edit.main(input) // my user-defined function. return base64 after edit image.
data = {"message": "Got base64", "base": edited_image, "type": imghdr.what(input)}
return Response(data=data)
No problem so far.
Promlem is from here.
I cannot get only base64 data of response that was sent from Django.
However, axios could get response from Django. I confirmed console.log()
/*this is react*/
useEffect(()=>{
async function check(ImagePath: string) {
window.electronAPI.server_on(); // electron starts server to work axios
await axios.post("http://127.0.0.1:8000/ImageEdit/edit/", {
input: ImagePath // input value of image path
})
.then((response)=>{
console.log("success: ", response); // <-- here, I confirmed response
})
this is result of console.log().
Then I run
console.log("base64: ", response.data.base);
However, nothing is shown. Even the text of "base64: " is disappear.
What I tried.
I tried whether I can take out the others value sent from Django.
I added value {"message": "Got base64"} in response of Django.
Then, I take out value like
console.log("message: ", response.data.message);
console.log("status: ", response.status);
They are successfuly shown. So, This may be problem of base64.
I confirmed capacity in POST method
I checked the length of base64 in Django. This was 34789440.
So, I made string value that has length of 40000000: t = "A"410**7
Then, I added this into response in Django, and I could receive it successfully in react.
convert to JSON before being sent from Django
I added the following code into view.py in Django.
...
data = {"message": "Got base64", "base": edited_image, "type": imghdr.what(input)}
params = json.dumps(data)
return Response(data=data)
The result was almost same the above my problem. console.log("success: ", response); showed
However, all response data became undefined. Even response.status became undefined.
check type of data
base64 was 'str'.
Why couldn't I take out only base64???
I googled it including how to use axios, Django post method and so on.
But I don't know how to fix it.
Thanks in advance.

Axios .get request weird behaviour

I have the following get request:
return axios
.get<ArticlesResponse>(SUGGESTED_ARTICLES, {
headers: {
'Content-Type': 'application/json',
},
})
.then(onRequestSuccess)
.catch(onRequestError);
It returns me an object with the data I need, however, the data field inside the object is a string instead of an actual object. Anyone has any ideea about why? I looked it up and saw that adding that header above will fix the issue but it doesn't. Thanks in advance!
My onRequestSucces is:
export function onRequestSuccess<T = any>(response: AxiosResponse<T>) {
console.log('Request Successful!', response);
return response.data;
}
JSON.Parse() also won't fix it.
The problem may be due to the API returning a response that contains invalid JSON data, now JSON.parse would throw an error, but Axios manages the exception by setting the invalid JSON as string in the data property. Try using the Fetch API.
Since you're using a GET request (doesn't have a body) the 'Content-Type' is not being useful. This header is used to tell the server which type of content you're sending, but you're sending none. You should use it only on POST/PUT requests.
See this question for more details on this.
In order for your request to be read as JSON you have to set the header in the server. This will tell the browser you're receiving a JSON, which will then be parsed automatically by axios.

How can I set cookie header using react and request-promise

"Cookie" header is never sent, even when browser console shows otherwise
I am trying to use request-promise and Reactjs to send request from my web application to SAP B1 Service Layer. First, I tried using the "headers" option in request-promise, then tried setting a cookie using rp.cookie("...") and jar.setCookie("...") but got errors both times.
The browser console is showing it is sending the "Cookie" header, but when I intercept the request using Burp Suite the header is never sent.
var rp = require('request-promise').defaults({jar:true});
var rd= require('request-debug');
rd(rp);
const b1jar=rp.jar();
let options = {
method: method,
rejectUnauthorized: false,
uri: url,
insecure:true,
jar:b1jar,
json: true,
resolveWithFullResponse:fullres,
// I TRIED TO USE THIS FIRST
headers:
{ 'Cookie': "B1SESSION="+(sessionStorage.SessionID||'')+';',
}
};
//THEN DELETED THE headers OPTION AND TRIED WITH THE jar OPTION
var b1cookie=rp.cookie('B1SESSION='+sessionStorage.SessionID);
b1cookie.setExpires(moment().add(sessionStorage.SessionTimeout,'m')
.toDate());
b1jar.setCookie(b1cookie,config.server);
res = await rp(options);
The expected result is that the B1SESSION Cookie should be sent when using rp(options), but it is not.
That API is pretty bad, try axios...
https://www.npmjs.com/package/react-axios

How to attach an Authorization header with a token when using Leaflet js

I am using Leaflet in my Angular.js map application. One of my resources requires an authorization header with token. I am using the leaflet-realtime plugin (found here: https://github.com/perliedman/leaflet-realtime) to get map updates and therefore need to be able to specify my header when realtime performs a fetch to get the data.
I first tried using another library, fetch-intercept (found here: https://github.com/werk85/fetch-intercept), to intercept the requests and attach the header, but the interceptor was being ignored. I included a console.log in the interceptor and it was never reached.
After more research, I noticed specifying headers is supposed to be supported: https://github.com/perliedman/leaflet-realtime/pull/83. However, I cannot find an example for how to properly attach an authorization token. Here is what I am currently trying:
this.mapRealtime = L.realtime({
url: this.getRealtimeUrl(),
crossOrigin: true,
headers: {"Authorization": "token"},
type: 'json',
},
However, when I check the Network logging from my web browser (Chrome) debugging console, all I see for the Request Headers is:
Provisional headers are shown
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
and the server returns status 403 with errortype MissingAuthenticationTokenException.
Can anyone provide an example of how to correctly attach the token? Thanks!
The realtime Leaflet only take url or json file path and you will be unable to pass headers(auth) as they have patch for it which is not working. I was facing same issue. What I did is following:
realtime = (L as any).realtime(async function (success, error) {
let geodataJson = await self.updateGeoJson();
success(geodataJson);
}, {
interval: 15 * 1000,
onEachFeature: onEachFeature,......
I have pass funtion to realtime and in that function I called simple API with headers
async updateGeoJson() {
await this.api.getMarkersGeoJson().subscribe((res: any) => {
this.geoData = res;
});
return this.geoData; }
On first call it will not get data in from this function so we also need to load data in this.geoData in ngOnInit before initmap.
For me it is working I know this is just work around but this issue is still in leaflet realtime. Hopefully this will work for you

Meteor redirect client from server-side method

Meteor 1.6, React, React Router
Interfacing with Paypal billing-agreements
Client onClick event:
subPayPal(){
Meteor.call('paypal.getToken', this.props.user_id, (error, response) => {
if(error) {
console.warn(error);
}else{
console.log(response);
}
}
}
I'm calling the method on the server rather than on the client because I'm dealing with privileged info (usernames, passwords, tokens, etc). No problem here.
Server methods:
Meteor.methods({
'paypal.getToken': function getOauthToken(uid){
// simplified a bit
// check if current token valid
// set vars here, then go get token
axios.post(ppAPI, data, config)
.then( function(response) {
// save oAuth token
})
.catch( function(error){
// stuff here
})
// prepare another axios.post(), with oauth Token, to get a payment token
// and approval_url and execute_url from paypal
// call axios.post() and use data in response:
// with the approval_url in this reponse, I need to redirect
// the browser to the approval_url on paypal.com so that the user
// can sign into paypal, and ok the subscription agreement.
// once user 'ok' in paypal, the browser comes back to my site,
// where I render a 'cart' with a final 'ok, purchase' button.
return approval_url;
}
})
So, once I have the approval_url, I can send it back to the client, and when the client "sees" it, it can then call the React Router to the paypal.com site.
PROBLEM
The client's onClick method is obviously async and as soon as I click the initial onClick(), the console.log outputs undefined for process which makes perfect sense.
TRIAL 1
So, I tried using Meteor.apply in the client trying to make it synchronous, waiting for the server-side method to return the approval_url to no avail:
subPayPal(){
Meteor.apply('paypal.getToken', [{uid:user_id}], {
onResultReceived: (error, response) => {
if(error) console.warn(error.reason);
if(response) console.log('server response', response);
}
});
}
I also tried Meteor.call('paypal.getToken').then({ console.log(response) }).catch... to no avail either, as it is still async.
I've also tried try/catch blocks in the server-side method, to no avail. Whatever I try, the server-side code always runs as expected (with exception of the Meteor.call().then().catch() which just plain failed). I just can't seem to promise it, or return it.
TRIAL 2
The next thought would be not caring about the response on the client, if I could get the server-side method, with approval_url defined, to somehow call the React Router on the client and push the unique approval_url to it, but that doesn't make much sense to me how to wire that up.
THOUGHT 1
I guess I could use some "temporary" database collection, which is reactive, so that when the server-side method completes, it'll update (or insert/create) a document, and when the client 'sees' that, it could then call the React Router to redirect the browser to paypal.com. The collection document would have to hold the approval_url URI, which would then be passed down to the client. Not too sure how I'd wire the client to tell the Router when it sees the approval_url "appear".
Sooooo....
Any ideas? Is there more than one solution (and if so, what would be the best?).
I read somewhere that the app should logout the user, then the Router could redirect to paypal, but that doesn't help, as paypal.com redirects back to me, and I wouldn't want the user to have to log back in again.
THANKS.

Resources