Open emily-curry opened 2 years ago
the issue https://github.com/facebook/react-native/issues/31641 is similar to here. Maybe that issue can be closed.
There are already several solutions in the https://github.com/facebook/react-native/issues/27099#issuecomment-1012775499 ,
such as copying the file and changing the image file extension or using rn-fetch-blob
library ( I didn't verify ).
Here are another solution:
customize a new handler to handle the request with file://
sheme and image type
add these two files to our own project. OriginImageRequestHandler.h OriginImageRequestHandler.mm
These two files just copy the contents of RCTFileRequestHandler
and increase the priority to 4 ( RCTImageLoader
is 2 ).
We can customize canHandleRequest
to handle the specified file if needed ( I only upload images in tmp directory ).
Here are default handlers in RCTNetworking.mm
:
I tested these two scenarios (use form-data
to upload compressed jpeg/png image):
RCTNetworking
will use RCTFileRequestHandler
to handle image file, the file size is same.
Because _loaders
in RCTImageLoader.mm
is not initialized.RCTNetworking
will use RCTImageLoader
sendRequest
to handle image file, the file size is larger.Of course, if these original images conform to the apple png/jpeg image storage format, the size will not become larger.
( e.g. upload an image saved using UIImagePNGRepresentation
or UIImageJPEGRepresentation(image, 1.0)
)
In addition. Here are some simplified call stacks for Image component (refrence)
require('./my-icon.png')
)
the uri is resolved to http://localhost:8081/assets/src/my-icon.png?platform=ios&hash=0d42d44c5312fdb4a2e7d42a9bfa8b0c
stack: RCTImageLoader
--> RCTNetworking
--> RCTHTTPRequestHandler
.uri: 'app_icon'
)
the uri is resolved to file:///xxx/xxx.png
stack: RCTImageLoader
--> RCTLocalAssetImageLoader
data:data:image/png;base64,xxxx
stack: RCTImageLoader
--> RCTNetworking
--> RCTDataRequestHandler
.The currently implemented handlers are: ...
- RCTImageRequestHandler - a handler for loading local images from the iOS asset-library
this revision added file RCTImageRequestHandler.m
to load local image with assets-library
or ph
sheme
Add pluggable image processing system
this revision deleted RCTImageRequestHandler.m
file and moved its function to the RCTImageLoader.m
,
added RCTAssetBundleImageLoader.m
to load local image (Its current name is RCTLocalAssetImageLoader.mm
)
Avoid re-encoding images when uploading local files (#31457)
this revision added a solution
Back out "Avoid re-encoding images when uploading local files" Summary: This was causing an upload error in FB Dating, will need to re-land with the fix.
this revision reverted f78526ce
If there is something wrong with the above, feel free to tell me. 🙂
Is there anything in the new architecture that we'd expect to fix this issue? I see this issue was marked with "Type: Old Architecture".
I think a good next step is to find out why the fix in #31457 was reverted, in e83feffe—I don't see any public discussion of that—and try to land an amended fix.
Is there anything in the new architecture that we'd expect to fix this issue? I see this issue was marked with "Type: Old Architecture".
Not really as this is related to networking/images which is unrelated to the New Architecture at all
this story is amazing.. A fix reverted for a dating app..
@ntdiary thanks for you solution, but I implemented it in a different way:
in my opinion we can just define the handlerPriority
in RCTFileRequestHandler
, in this way you don't need to copy the file -> duplicate the code..
this handlerPriority
looks to be used only in the network directory so I hope it is safe to do it..
By the way the images are display in the app, and the upload is correctly done..
here the patch:
diff --git a/node_modules/react-native/Libraries/Network/RCTFileRequestHandler.mm b/node_modules/react-native/Libraries/Network/RCTFileRequestHandler.mm
index 19d025c..519c860 100644
--- a/node_modules/react-native/Libraries/Network/RCTFileRequestHandler.mm
+++ b/node_modules/react-native/Libraries/Network/RCTFileRequestHandler.mm
@@ -92,6 +92,22 @@ - (void)cancelRequest:(NSOperation *)op
return nullptr;
}
+/**
+ * Add this function to give precedence to the file upload instead of image upload. the image upload is changing the file
+ * with no reason.
+ * this handlerPriority is used only in the RCTNetworking.mm and this file is in defined in the network directory so I hope is not used
+ * else where
+ * for the bug see:
+ * https://github.com/facebook/react-native/issues/27099
+ * https://github.com/facebook/react-native/pull/31457
+ * https://github.com/facebook/react-native/commit/e83feffeba567b4e304181632128ee1caa036c45
+ * https://github.com/facebook/react-native/issues/33760
+*/
+- (float)handlerPriority
+{
+ return 3;
+}
+
@end
Class RCTFileRequestHandlerCls(void)
I don't know why it was work, but I think maybe this can help guys.
I have the same issue, but when I try to add the base64 into formData
the issue was been solved.
from
formData.append('file', { type: 'image/jpg', name: 'image.jpg', uri: fileUri });
to
formData.append('file', { type: 'image/jpg', name: 'image.jpg', uri: fileUri, base64: '/9j/4AA.....' });
*I get these data by react-native-image-picker
I don't know why it was work, but I think maybe this can help guys.
I have the same issue, but when I try to add the base64 into
formData
the issue was been solved.from
formData.append('file', { type: 'image/jpg', name: 'image.jpg', uri: fileUri });
to
formData.append('file', { type: 'image/jpg', name: 'image.jpg', uri: fileUri, base64: '/9j/4AA.....' });
*I get these data by react-native-image-picker
Thanks buddy - looks like it is working right now! :) Passing base64 string through components and functions won't make app laggy?
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.
This issue was closed because it has been stalled for 7 days with no activity.
This issue is not stale! We're still waiting for the fix that was backed out in https://github.com/facebook/react-native/commit/e83feffe to be re-landed or replaced with a new fix.
Reopening as we believe this is still an issue.
Also related to:
Description
When creating a
multipart/form-data
request with aFormData
object whose parts contain auri
property pointing to an image file, the resulting network request is much (~3-4 times) larger than the original image file.This issue only occurs on iOS. This is a duplicate of #27099, which has been closed but is not fixed.
Version
0.67.3
Output of
npx react-native info
Steps to reproduce
Obtain a URI to any on-disk image, call it
fileUri
. Create aFormData
object with the file uri:Then, make a request with that form data:
Observe the content-length of the request headers if you control the server, or in this example, observe the response body from postman-echo.
Snack, code example, screenshot, or link to a repository
Snack demonstrating issue (and current workaround): https://snack.expo.dev/@httpriestess/image-upload-size-repro
It posts an image file to postman-echo, and then displays the content-length header that postman-echo returns.