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

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.

Related

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

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?

(ReactJS, Axios) Posting file to API result in an HTTP request with no payload

I've been stuggling with this problem for several hours now, and as I feel like I browsed all StackOverflow, I therefore am making my first post here, after almost a decade of working in IT ! 😎
Long story short, I have to send a file (an image) to my API (Express 4/Multer), and I am using Axios for that.
Below is what the form submit part looks like at the moment :
let avatar = e.target.avatar.files[0];
[...]
if (avatar) {
let formData = new FormData();
formData.append("avatar", avatar);
let customHeaders = {
"Content-Type":
"multipart/form-data" + ";boundary=xxMyBoundaryxx",
};
console.log(avatar); // This is not empty !
console.log(formData.get('avatar')); // Neither is this !
axios.post(
apiUrl,
formData,
customHeaders
);
}
Everything is good server-side, I used Insomnia to test uploading a file to my apiUrl, and it is working like a charm.
Also, if I remove my boundary parameter in Content-Type, it triggers an error ('Multipart: Boundary not found').
However, when I post my file using the code above, the resulting HTTP request has no payload, meaning that the data given to my API is empty (checked using Chrome).
I've been trying to understand the problem, and
Hope my description was not too vague, and that my english was not too bad 😓
Feel free to reach me if you are missing something to give an answer,
Regards,
Hazreath
PS :
Server side "Multipart: boundary not found" error message :
Error: Multipart: Boundary not found
at new Multipart (C:\Workspace\React\Tricks\back\node_modules\busboy\lib\types\multipart.js:58:11)
at Multipart (C:\Workspace\React\Tricks\back\node_modules\busboy\lib\types\multipart.js:26:12)
at Busboy.parseHeaders (C:\Workspace\React\Tricks\back\node_modules\busboy\lib\main.js:71:22)
at new Busboy (C:\Workspace\React\Tricks\back\node_modules\busboy\lib\main.js:22:10)
at multerMiddleware (C:\Workspace\React\Tricks\back\node_modules\multer\lib\make-middleware.js:33:16)
at Layer.handle [as handle_request] (C:\Workspace\React\Tricks\back\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Workspace\React\Tricks\back\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Workspace\React\Tricks\back\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Workspace\React\Tricks\back\node_modules\express\lib\router\layer.js:95:5)
at C:\Workspace\React\Tricks\back\node_modules\express\lib\router\index.js:281:22
The form boundary part and the entire content-type header should not be defined by the user if you use the native FormData encoder.
Using Axios v0.27.2:
const formData = new FormData();
formData.append('avatar', avatar);
axios.post(apiUrl, formData);
Or:
axios.postForm(apiUrl, {
avatar
});
Or you can just submit the entire FileList object
axios.post(apiUrl, document.querySelector('#fileInput').files);
Playground

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.

ReactJS image/pdf file download not working

I want to download file that can be in any format viz. pdf, jpeg, png, xlsx, csv etc. The download API on backend using pyramid framework is sending FileResponse as below:
def delivery_item_download_view(request, *args, **kw):
context = request.context
item_row = context.item_row
if item_row and item_row["deleted_at"] is None:
print(request.upload_dir+'/'+item_row["file_name"]+'.'+item_row["file_extension"])
response = FileResponse(
request.upload_dir+'/'+item_row["file_name"]+'.'+item_row["file_extension"],
request=request,
)
response.headers["attachment"] = item_row["name"];
return response
This, when executed using POSTMAN works as expected giving file as output. However,when tried implementing same using ReactJS, it's not working as expected. My client-code is as below:
onDownloadItem= (item) => {
console.log("item id is:", item.item_id)
var apiBaseUrl = "https://dev.incodax.com/api/deliveries_items/"+ item.item_id+ "/download";
fetch(apiBaseUrl, {
method: "GET",
}).then((res) => {
fileDownload(res,item.file_name)
console.log(res)
})
}
This fileDownload function simply downloading file but with no content inside. In downloaded file I could see something like:
[object Response]
I am getting 200 response from server. So I dont't think there is any issue with server side code. How can I handle it on client?
Thanks in advance
Will it suit you if you just redirected user to link to file? Browser will automatically handle it and download it.
The issue is in your fileDownload function which you do not post here. It's not clear what the first parameter is supposed to be but likely it is not the response object. Likely you at least need to pull the body out of the response and save that! The response body can be converted to a buffer object which could work (again it depends on what fileDownload is expecting):
res.arrayBuffer().then(buffer => {
fileDownload(buffer, item.file_name);
});

Error 400 when POST'ing JSON in angularjs + Spark Single Page Application

I'm new to Single Page Application area and I try to develop app using angularjs and Spark framework. I get error 400 bad request when I want to post JSON from my website. Here is code fragment from client side:
app.controller('PostTripCtrl', function($scope, $http) {
$scope.newTrip = {};
$scope.submitForm = function() {
$http({
method : 'POST',
url : 'http://localhost:4567/trips/add',
data : $scope.newTrip,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
}
}).success(function(data) {
console.log("ok");
}).error(function(data) {
console.log("error");
console.log($scope.newTrip);
});
};
});
Values that are to be assigned to newTrip are read from appropriate inputs in html file. Here is server-side fragment:
post("/trips/add", (req, res) -> {
String tripOwner = req.queryParams("tripOwner");
String startDate = req.queryParams("startDate");
String startingPlace = req.queryParams("startingPlace");
String tripDestination = req.queryParams("tripDestination");
int tripPrice = Integer.parseInt(req.queryParams("tripPrice"));
int maxNumberOfSeats = Integer.parseInt(req.queryParams("maxNumberOfSeats"));
int seatsAlreadyOccupied = Integer.parseInt(req.queryParams("seatsAlreadyOccupied"));
tripService.createTrip(tripOwner, startDate, startingPlace, tripDestination, tripPrice, maxNumberOfSeats,
seatsAlreadyOccupied);
res.status(201);
return null;
} , json());
At the end I obtain error 400 bad request. It is strange for me that when I want to see output on the console
System.out.println(req.queryParams());
I get json array of objects with values written by me on the website. However, when I want to see such output
System.out.println(req.queryParams("tripOwner"));
I get null. Does anyone have idea what is wrong here?
I think the main problem is that you are sending data to your Spark webservice with the 'Content-Type' : 'application/x-www-form-urlencoded' header. Try sending it as 'Content-Type' : 'application/json' instead, then in your Java code declare a String to receive req.body(), you'll see all your data in there.
Note: When you try to acces your data like this req.queryParams("tripOwner"); you're not accessing post data, but you're seeking for a get parameter called tripOwner, one that could be sent like this http://localhost:8080/trips/add?tripOwner=MyValue.
I would advise using postman to post a request to your server and see if it works. Try a different content type too. Try using curl and play with the various headers you are sending. 400 suggests the wrong data is being sent or expected data is missing or the data is the wrong type but based on your code you've provided I can see nothing wrong (but see below).
When your server receives a request log all request headers being received and see what changing them does. If it works in postman then you can change your client code to mirror the headers postman is using.
Does your spark server validate the data being sent before your controller code is hit? If so ensure you are adhering to all validation rules
Also on looking at your code again your client is sending the data in the post data but your server is expecting the data in the query string and not in the post data?
What happens if your server just sends a 201 response and does nothing else? Does your client get a 201 back? If so it suggests the hook up is working but there is something wrong with the code before you return a 201, build it up slowly to fix this.
Ok, I managed to cope with that using another approach. I used Jackson and ObjectMapper according to Spark documentantion. Thanks for your answers.
You can see more about that here: https://sparktutorials.github.io/2015/04/03/spark-lombok-jackson-reduce-boilerplate.html
You're probably just needed to enable CORS(Cross-origin resource sharing) in your Spark Server, which would have allowed you to access the REST resources outside the original domain of the request.
Spark.options("/*", (request,response)->{
String accessControlRequestHeaders = request.headers("Access-Control-Request-Headers");
if (accessControlRequestHeaders != null) {
response.header("Access-Control-Allow-Headers", accessControlRequestHeaders);
}
String accessControlRequestMethod = request.headers("Access-Control-Request-Method");
if(accessControlRequestMethod != null){
response.header("Access-Control-Allow-Methods", accessControlRequestMethod);
}
return "OK";
});
Spark.before((request,response)->{
response.header("Access-Control-Allow-Origin", "*");
});
Read more about pre-flighted requests here.

Resources