NextJS, fetch, multipart/form-data, missing boundary - next.js

I've faced with issue while proxy http request with multipart form data by NextJS. I have to send file from a client fide to next js, after that - to FastApi service.
The problem was:
fetch("https://127.0.0.1:3000/api/newfile", {
method: "POST",
headers: { "Content-Type": "multipart/form-data" },
body: new FormData(form)
});
headers request: "Content-Type: multipart/form-data"
In order for NextJS API to parse the file, you need a header with boundary
Something like this:
multipart/form-data; boundary=----< generate boundary >
For a long time I could not figure out how to get it.
There is an exit. It is necessary not to fill in "Content-Type".
And then the browser itself will generate this header by passing the form-data.
For example:
fetch("https://127.0.0.1:3000/api/newfile", {
method: "POST",
headers: {},
body: new FormData(form)
});
I also noticed that the problem concerns fetch
When I used XMLHttpRequest I didn't face such problem.
Further, the header can easily be passed further to FastAPI
in API:
req.headers["content-type"]

Related

NextJs - Use fetch() to make api call with POST method - always ERR_ABORTED 400

when I try to make api call with fetch() method and request type is POST, then I receive error in console: "POST ... ERR_ABORTED 400 (Bad request)"
btw. I have used 'no-cors' mode because api url is on different domain, I know that this is not best approach. For now I just want to make it to work and later I will deal with CORS issue that I have when mode is not set to 'no-cors'.
const res = await fetch(apiUrl, {
method: 'POST',
body: JSON.stringify({
sku: sku
}),
headers: {
'Authorization': 'Bearer ' + jwtToken,
'Content-Type': 'application/json'
},
mode: "no-cors"
});
What can be the cause why fetch() method always returns error, maybe something with the syntax? Both "sku" and "jwtToken" variables are set.
I tried it with postman and everything works fine, but when I try to make that api call inside nextjs then its not working.

How can I pass parameters in javascript fetch call

I'm integrating Stripe payments in an aspx site (VB, .NET 4.7.2).
I took Javascripts from Stripe samples.
I try to call this method of the backend:
<WebMethod()>
Public Shared Function CreateStripePaymentIntent(ByVal aPrice As String) As PaymentIntent
...
End Function
from a Javascript in the page:
(here the parameter is a fixed value, to simplify)
fetch("PayOrder.aspx/CreateStripePaymentIntent?aPrice=111", {
method: "POST",
headers: {
'Accept': 'application/json',
"Content-Type": "application/json"
}
body: JSON.stringify(purchase)
})
If I remove the parameter all works well (but is useless).
If I try to pass the parameter I always have error 500:
POST http://localhost:14987/PayOrder.aspx/CreateStripePaymentIntent?aPrice=111
Status 500
Internal Server Error
Version HTTP/1.1
Transferred 0,98 kB (660 B size)
Referrer Policy strict-origin-when-cross-origin
Message "No value for parameter 'aPrice'." (my translation from italian to english!)
Someone can tell me WHY this parameter does not reach the backend?
The values are sent in the request body, in the format that the content type specifies.
Usually the content type is application/x-www-form-urlencoded, so the request body uses the same format as the query string:
parameter=value&also=another
When you use a file upload in the form, you use the multipart/form-data encoding instead, which has a different format. It's more complicated, but you usually don't need to care what it looks like, so I won't show an example, but it can be good to know that it exists.
for Json content type is application/json
fetch("PayOrder.aspx/CreateStripePaymentIntent", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ aPrice: 111 })
})

My API makes multiple requests to the server

I'm not sure why, I'll press the button once, and I'll get 4 log events that are all the same except for the timestamp. Is there a way for me to prevent the multiple API calls or should I see if I can merge these multiple log events (stored as objects) in my database.
This is what my fetch request looks like:
fetch(apiUrl + "/api/first/registration", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
data: data.data,
}),
On my server side I immediately send a res.status(200) if it's successful.
Should I try Axios instead? Would that fix the problem?

Getting 401 on API but working with postMan

I have this API:
const url = url;
const headers = new Headers({
"Content-Type": "application/json",
"Accept": "application/json", // change to application/javascript for jsonp
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Origin": true,
"access_token": accessToken,
"id_token": idToken,
});
const options = {
method: "GET",
headers: headers,
credentials: "same-origin",
mode: "no-cors"
};
fetch(url, options)
.then(function(response) {
console.log('-working: ',response.json());
})
.catch(function(error) {
console.log('-error: ',error);
});
Having the same API on postMan this works like a charm there but on my code I always get 401 (Unauthorized).
Also if I remove "no-cors" I get a 401 plus CORS issue
I was having the same issue.
My senior said, that CORS is not safe, so first compare the headers of both the requests.
I would suggest you use Wireshark to see the the header that is being sent from both the requests.
Steps(step 3 and 4 is for conveniently spotting your requests):
Install Wireshark.
Select the network connection that you are using for the calls(for eg, select the Wifi if you are using it)
There will be many requests and responses, close extra applications.
Usually the requests are in green color, once you spot your request, copy the destination address and use the filter on top by
typing ip.dst==52.187.182.185 by putting the destination address.
Tap on your request made by postman and by your call.
Compare both the headers.
In my case, I was calling the API from my react native app, and the header parameter was getting converted into lowercase automatically.
So, to correct it, I made the parameter in lowercase in backend server.
Play "Spot the difference" between the two windows and find yours.
If this doesn't work, go with setting up CORS.
CORS needed to be added as an additional header on the back end

I see the response body in chrome developer tools, but unable to retrieve it inside Front End

I am currently working in a project where I need to send a response from grails back end to ReactJs front End. I was able to send the response from grails controller using "response" but unable to extract the response body on the ReactJs side. I tried checking in the following and found null value or undefined.
response.content, response.body
I see the response I sent back from grails in chrome web developer tools "Network" tab. but unable to find out which field of response object actually has it. Any help regarding this will be highly appreciated.
My http request.
post: function(url, item) {
return fetch(baseUrl + url, {
headers: {
'Accept': 'text/plain',
'Content-Type': 'text/plain'
},
method: 'post',
body: item
}).then(function(response) {
alert(response);
return response ;
});
},
grails
response << "there is an error"
Try render 'there is an error'
Or if you need to render JSON:
render [someKey: 'there is an error'] as JSON
To understand how grails controllers and views work read this simple example.
Have you tried content-type: 'application/json'

Resources