Fix: Use data URL iframe with auto-submitting form for Collabora POST

- Create iframe with data URL containing HTML page
- HTML page has form that auto-submits to loleaflet.html with WOPISrc in body
- This ensures POST request instead of GET
- Form submits within iframe context, not affected by parent page JavaScript
This commit is contained in:
Leon Bösche
2026-01-12 15:34:43 +01:00
parent 99419748bb
commit 0ee3b32ef3

View File

@@ -450,21 +450,12 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
Widget _buildCollaboraIframe(String wopisrc) { Widget _buildCollaboraIframe(String wopisrc) {
// For Collabora Online, we need to POST the WOPISrc, not GET it // For Collabora Online, we need to POST the WOPISrc, not GET it
// Use JavaScript to create and submit the form properly // Create an HTML page with auto-submitting form and set as iframe src
final String viewType = 'collabora-form-${DateTime.now().millisecondsSinceEpoch}'; final String viewType = 'collabora-form-${DateTime.now().millisecondsSinceEpoch}';
ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) { ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) {
// Create a container for the form and iframe // Create the iframe
final container = html.DivElement()
..style.width = '100%'
..style.height = '100%'
..style.margin = '0'
..style.padding = '0'
..style.overflow = 'hidden';
// Create the iframe first
final iframe = html.IFrameElement() final iframe = html.IFrameElement()
..name = 'collabora-iframe-$viewId'
..style.border = 'none' ..style.border = 'none'
..style.width = '100%' ..style.width = '100%'
..style.height = '100%' ..style.height = '100%'
@@ -479,38 +470,36 @@ class _DocumentViewerModalState extends State<DocumentViewerModal> {
'allow-scripts allow-popups allow-forms allow-pointer-lock allow-presentation allow-modals allow-downloads allow-popups-to-escape-sandbox', 'allow-scripts allow-popups allow-forms allow-pointer-lock allow-presentation allow-modals allow-downloads allow-popups-to-escape-sandbox',
); );
container.append(iframe); // Create an HTML page with an auto-submitting form
final htmlContent = '''
// Use JavaScript to create and submit the form <!DOCTYPE html>
// This is more reliable than Dart's form.submit() <html>
final jsCode = ''' <head>
(function() { <title>Loading...</title>
var form = document.createElement('form'); </head>
form.method = 'POST'; <body style="margin: 0; padding: 0;">
form.action = 'https://of.b0esche.cloud/loleaflet/dist/loleaflet.html'; <form method="POST" action="https://of.b0esche.cloud/loleaflet/dist/loleaflet.html" style="display: none;">
form.target = 'collabora-iframe-$viewId'; <input type="hidden" name="WOPISrc" value="$wopisrc">
form.style.display = 'none'; </form>
<script>
var input = document.createElement('input'); document.forms[0].submit();
input.type = 'hidden'; </script>
input.name = 'WOPISrc'; </body>
input.value = '$wopisrc'; </html>
form.appendChild(input);
document.body.appendChild(form);
// Submit the form
setTimeout(function() {
form.submit();
}, 50);
})();
'''; ''';
final script = html.ScriptElement() // Set iframe src to a data URL with the form
..type = 'text/javascript' final dataUrl = 'data:text/html;charset=utf-8,${Uri.encodeComponent(htmlContent)}';
..text = jsCode; iframe.src = dataUrl;
html.document.body!.append(script); // Create a container
final container = html.DivElement()
..style.width = '100%'
..style.height = '100%'
..style.margin = '0'
..style.padding = '0'
..style.overflow = 'hidden'
..append(iframe);
return container; return container;
}); });