You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Fizz] Fallback to client replaying actions if we're trying to serialize a Blob (#28987)
This follows the same principle as in #28611.
We cannot serialize Blobs of a form data into HTML because you can't
initialize a file input to some value. However the serialization of
state in an Action can contain blobs. In this case we do error but
outside the try/catch that recovers to error to client replaying instead
of MPA mode. This errors earlier to ensure that this works.
Testing this is a bit annoying because JSDOM doesn't have any of the
Blob methods but the Blob needs to be compatible with FormData and the
FormData needs to be compatible with `<form>` nodes in these tests. So I
polyfilled those in JSDOM with some hacks.
A possible future enhancement would be to encode these blobs in a base64
mode instead and have some way to receive them on the server. It's just
a matter of layering this. I think the RSC layer's `FORM_DATA`
implementation can pass some flag to encode as base64 and then have
decodeAction include some way to parse them. That way this case would
work in MPA mode too.
DiffTrain build for [6bac4f2](6bac4f2)
Copy file name to clipboardExpand all lines: compiled/facebook-www/ReactDOMServer-dev.classic.js
+24-7Lines changed: 24 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ if (__DEV__) {
19
19
varReact=require('react');
20
20
varReactDOM=require('react-dom');
21
21
22
-
varReactVersion='19.0.0-www-classic-f3d84129';
22
+
varReactVersion='19.0.0-www-classic-b547cfd9';
23
23
24
24
// This refers to a WWW module.
25
25
varwarningWWW=require('warning');
@@ -2572,11 +2572,7 @@ var startHiddenInputChunk = stringToPrecomputedChunk('<input type="hidden"');
2572
2572
functionpushAdditionalFormField(value,key){
2573
2573
vartarget=this;
2574
2574
target.push(startHiddenInputChunk);
2575
-
2576
-
if(typeofvalue!=='string'){
2577
-
thrownewError('File/Blob fields are not yet supported in progressive forms. '+'It probably means you are closing over binary data or FormData in a Server Action.');
2578
-
}
2579
-
2575
+
validateAdditionalFormField(value);
2580
2576
pushStringAttribute(target,'name',key);
2581
2577
pushStringAttribute(target,'value',value);
2582
2578
target.push(endOfStartTagSelfClosing);
@@ -2589,14 +2585,35 @@ function pushAdditionalFormFields(target, formData) {
2589
2585
}
2590
2586
}
2591
2587
2588
+
functionvalidateAdditionalFormField(value,key){
2589
+
if(typeofvalue!=='string'){
2590
+
thrownewError('File/Blob fields are not yet supported in progressive forms. '+'Will fallback to client hydration.');
2591
+
}
2592
+
}
2593
+
2594
+
functionvalidateAdditionalFormFields(formData){
2595
+
if(formData!=null){
2596
+
// $FlowFixMe[prop-missing]: FormData has forEach.
Copy file name to clipboardExpand all lines: compiled/facebook-www/ReactDOMServer-dev.modern.js
+24-7Lines changed: 24 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ if (__DEV__) {
19
19
varReact=require('react');
20
20
varReactDOM=require('react-dom');
21
21
22
-
varReactVersion='19.0.0-www-modern-f9bdfca0';
22
+
varReactVersion='19.0.0-www-modern-ce28692a';
23
23
24
24
// This refers to a WWW module.
25
25
varwarningWWW=require('warning');
@@ -2572,11 +2572,7 @@ var startHiddenInputChunk = stringToPrecomputedChunk('<input type="hidden"');
2572
2572
functionpushAdditionalFormField(value,key){
2573
2573
vartarget=this;
2574
2574
target.push(startHiddenInputChunk);
2575
-
2576
-
if(typeofvalue!=='string'){
2577
-
thrownewError('File/Blob fields are not yet supported in progressive forms. '+'It probably means you are closing over binary data or FormData in a Server Action.');
2578
-
}
2579
-
2575
+
validateAdditionalFormField(value);
2580
2576
pushStringAttribute(target,'name',key);
2581
2577
pushStringAttribute(target,'value',value);
2582
2578
target.push(endOfStartTagSelfClosing);
@@ -2589,14 +2585,35 @@ function pushAdditionalFormFields(target, formData) {
2589
2585
}
2590
2586
}
2591
2587
2588
+
functionvalidateAdditionalFormField(value,key){
2589
+
if(typeofvalue!=='string'){
2590
+
thrownewError('File/Blob fields are not yet supported in progressive forms. '+'Will fallback to client hydration.');
2591
+
}
2592
+
}
2593
+
2594
+
functionvalidateAdditionalFormFields(formData){
2595
+
if(formData!=null){
2596
+
// $FlowFixMe[prop-missing]: FormData has forEach.
@@ -5691,4 +5699,4 @@ exports.renderToString = function (children, options) {
5691
5699
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
@@ -5669,4 +5677,4 @@ exports.renderToString = function (children, options) {
5669
5677
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
Copy file name to clipboardExpand all lines: compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js
+23-6Lines changed: 23 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -2569,11 +2569,7 @@ var startHiddenInputChunk = stringToPrecomputedChunk('<input type="hidden"');
2569
2569
functionpushAdditionalFormField(value,key){
2570
2570
vartarget=this;
2571
2571
target.push(startHiddenInputChunk);
2572
-
2573
-
if(typeofvalue!=='string'){
2574
-
thrownewError('File/Blob fields are not yet supported in progressive forms. '+'It probably means you are closing over binary data or FormData in a Server Action.');
2575
-
}
2576
-
2572
+
validateAdditionalFormField(value);
2577
2573
pushStringAttribute(target,'name',key);
2578
2574
pushStringAttribute(target,'value',value);
2579
2575
target.push(endOfStartTagSelfClosing);
@@ -2586,14 +2582,35 @@ function pushAdditionalFormFields(target, formData) {
2586
2582
}
2587
2583
}
2588
2584
2585
+
functionvalidateAdditionalFormField(value,key){
2586
+
if(typeofvalue!=='string'){
2587
+
thrownewError('File/Blob fields are not yet supported in progressive forms. '+'Will fallback to client hydration.');
2588
+
}
2589
+
}
2590
+
2591
+
functionvalidateAdditionalFormFields(formData){
2592
+
if(formData!=null){
2593
+
// $FlowFixMe[prop-missing]: FormData has forEach.
0 commit comments