Fix Collabora Online loading using form-based POST instead of URL params
- Collabora's loleaflet.html expects WOPISrc as POST parameter, not URL query param - Changed from iframe with src= to form submission approach - Extract WOPISrc from URL and pass as hidden form input - This avoids 400 Bad Request from Collabora when using GET with URL params
This commit is contained in:
@@ -404,8 +404,9 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
|
|||||||
final wopiSession = snapshot.data!;
|
final wopiSession = snapshot.data!;
|
||||||
|
|
||||||
// Build Collabora Online viewer URL with WOPISrc
|
// Build Collabora Online viewer URL with WOPISrc
|
||||||
|
// Note: Don't double-encode the WOPISrc - Collabora expects the URL as-is
|
||||||
final collaboraUrl =
|
final collaboraUrl =
|
||||||
'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html?WOPISrc=${Uri.encodeComponent(wopiSession.wopisrc)}';
|
'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html?WOPISrc=${wopiSession.wopisrc}';
|
||||||
|
|
||||||
// Use WebView to display Collabora Online
|
// Use WebView to display Collabora Online
|
||||||
return _buildWebView(collaboraUrl);
|
return _buildWebView(collaboraUrl);
|
||||||
@@ -453,31 +454,69 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCollaboraIframe(String collaboraUrl) {
|
Widget _buildCollaboraIframe(String collaboraUrl) {
|
||||||
// Register the iframe element
|
// For Collabora Online, we need to use a form-based approach instead of iframe
|
||||||
const String viewType = 'collabora-iframe';
|
// because loleaflet.html expects a POST request with WOPISrc in the body
|
||||||
|
|
||||||
// Create the iframe with proper attributes for Collabora Online
|
const String viewType = 'collabora-form-container';
|
||||||
ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) {
|
|
||||||
final iframe = html.IFrameElement()
|
ui.platformViewRegistry.registerViewFactory(
|
||||||
..src = collaboraUrl
|
viewType,
|
||||||
..style.border = 'none'
|
(int viewId) {
|
||||||
..style.width = '100%'
|
// Create a container div for the form and iframe
|
||||||
..style.height = '100%'
|
final container = html.DivElement()
|
||||||
..style.margin = '0'
|
..style.width = '100%'
|
||||||
..style.padding = '0'
|
..style.height = '100%'
|
||||||
..setAttribute(
|
..style.margin = '0'
|
||||||
|
..style.padding = '0';
|
||||||
|
|
||||||
|
// Create a hidden form to POST to Collabora
|
||||||
|
final form = html.FormElement()
|
||||||
|
..method = 'POST'
|
||||||
|
..action = 'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html'
|
||||||
|
..target = 'collabora-frame'
|
||||||
|
..style.display = 'none';
|
||||||
|
|
||||||
|
// Extract the WOPISrc value from the URL
|
||||||
|
final wopisrcValue = collaboraUrl.split('WOPISrc=').length > 1
|
||||||
|
? collaboraUrl.split('WOPISrc=')[1]
|
||||||
|
: '';
|
||||||
|
|
||||||
|
final wopisrcInput = html.InputElement()
|
||||||
|
..type = 'hidden'
|
||||||
|
..name = 'WOPISrc'
|
||||||
|
..value = wopisrcValue;
|
||||||
|
|
||||||
|
form.append(wopisrcInput);
|
||||||
|
container.append(form);
|
||||||
|
|
||||||
|
// Create the iframe
|
||||||
|
final iframe = html.IFrameElement()
|
||||||
|
..name = 'collabora-frame'
|
||||||
|
..style.border = 'none'
|
||||||
|
..style.width = '100%'
|
||||||
|
..style.height = '100%'
|
||||||
|
..style.margin = '0'
|
||||||
|
..style.padding = '0';
|
||||||
|
|
||||||
|
// Set sandbox attributes
|
||||||
|
iframe.setAttribute(
|
||||||
|
'sandbox',
|
||||||
|
'allow-same-origin allow-scripts allow-popups allow-forms allow-top-navigation allow-pointer-lock allow-presentation allow-modals allow-downloads',
|
||||||
|
);
|
||||||
|
|
||||||
|
iframe.setAttribute(
|
||||||
'allow',
|
'allow',
|
||||||
'microphone; camera; usb; autoplay; clipboard-read; clipboard-write',
|
'microphone; camera; usb; autoplay; clipboard-read; clipboard-write',
|
||||||
);
|
);
|
||||||
|
|
||||||
// Prevent sandbox restrictions that might block Collabora
|
container.append(iframe);
|
||||||
iframe.setAttribute(
|
|
||||||
'sandbox',
|
|
||||||
'allow-same-origin allow-scripts allow-popups allow-forms allow-top-navigation allow-pointer-lock allow-presentation allow-modals',
|
|
||||||
);
|
|
||||||
|
|
||||||
return iframe;
|
// Submit the form to load the document
|
||||||
});
|
form.submit();
|
||||||
|
|
||||||
|
return container;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return HtmlElementView(viewType: viewType);
|
return HtmlElementView(viewType: viewType);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user