I’m trying to work on localhost integration of CODE run via docker, but I faced some problem with using PostMessage.
I have my localhost FastApi WOPI server, and it works perfectly with simple CheckFileInfo or PutFile operations (document is retrieved and saved correctly). However, when I click on “Save As” button, nothing happens in UI (I have “UserCanNotWriteRelative” set to false). I figured out that I need to use PostMessages, so I have .html file with iframe that listens on message events.
The problem is that it doesn’t work correctly, the result is similar to the one described in this topic. If “PostMessageOrigin” is set to “http://localhost:8888” (the address of the page where html is running and WOPI server) or any other value, including CODE’s address on localhost, the only AppLoading status I get is “Initialized”. Without PostMessageOrigin I can respond with “Host_PostmessageReady”.
After that I get “UI_SaveAs” message, and I try to post to the same target the following message:
The core issue (no WOPI request after Action_SaveAs) is still PostMessage origin mismatch, not the Notify flag.
PostMessageOrigin (WOPI server config): Must be the exact URL of your HTML host page (e.g., http://localhost:8888).
targetOrigin (your postMessage to CODE): Must be the exact URL of the CODE iframe (e.g., http://localhost:9980).
Explanation: CODE is rejecting your Action_SaveAs message because of security/origin issues, preventing it from even attempting the PutRelativeFile. While Notify: true is good for getting a save confirmation (Action_Save_Resp), it won’t fix this initial communication breakdown.
Read Action_SaveAs carefully and checkout the full working of the postmessage api
Unfortunately, it didn’t solve the issue. I added PostMessageOrigin again, set it to html template url with local network ip (given by ip addr) and opened fastapi app with the same address. I also tried it with localhost, too, but with no success - now it doesn’t even send Host_PostmessageReady because there is no Document_Loaded status.
Here is .html script code where I tried both using event origin and specific targetOrigin:
function post(target, msgId, values) {
document.querySelector("#collaboraFrame").contentWindow.postMessage({MessageId: msgId, SendTime: Date.now(), ...(values && {Values: values})}, target);
console.log("hello")
}
function postReady(target) {
post(target, 'Host_PostmessageReady');
}
function receiveMessage(event) {
console.log('==== receiveMessage: ' + JSON.stringify(event.data));
console.log(event)
let msg = JSON.parse(event.data || '{}');
if (!msg) {
return;
}
if (msg?.MessageId == 'App_LoadingStatus') {
if (msg.Values) {
console.log("IF WORKED")
if (msg.Values.Status == 'Document_Loaded') {
console.log("POSTING")
postReady(e.origin)
}
}
} else if (msg?.MessageId === "UI_InsertGraphic") {
post({
MessageId: "Action_InsertGraphic",
Values: {
url: current_graphics
}
});
} else if (msg?.MessageId === 'UI_SaveAs') {
console.log("SAVEAS")
post('Action_SaveAs', {
Filename: "hello.xlsx"
})
}
console.log(msg?.MessageId);
}
(Here target filename is hard coded for debugging purposes, initially it was assigned in dialog window)
Your script has a critical error in how you’re sending messages back to CODE, which explains why nothing happens and Host_PostmessageReady isn’t sent.What’s wrong:
Incorrect targetOrigin for postMessage: In your post function, the target parameter is meant for the origin URL of the iframe you’re posting to.
You are mistakenly passing message IDs like ‘Action_SaveAs’ directly as the target (origin) for postMessage in calls like post(‘Action_SaveAs’, {Filename: “hello.xlsx”}). This is wrong.
Solution: You need to pass the actual URL origin of the CODE iframe (e.g., http://localhost:9980) as the targetOrigin for all messages you send back to CODE. Capture event.origin when CODE sends you messages and use that consistently.
JSON.parse(event.data || ‘{}’): CODE messages are usually already JavaScript objects. Parsing them as JSON will cause errors. Remove this line.
App_LoadingStatus for Host_PostmessageReady: CODE typically expects Host_PostmessageReady after App_LoadingStatus with Status: ‘Initialized’, not Document_Loaded.
Fixing these script errors, combined with ensuring your FastApi’s PostMessageOrigin precisely matches your HTML host’s URL, will likely solve your problem.
At least first code message is not JS object completely, event.data is a string, so without JSON.parseif msgId === ... is not even triggered
I’ve also tried responding to “Initialized” before, it didn’t help.
As for target: tried using http://192.168.250.47:9980 as well as https://192.168.250.47:9980(192.168.250.47 is my LAN-ip, and I use SSC for self-hosted https) as targetOrigin in postMessage, and PostMessageOrigin is set to "http://192.168.250.47:8888"
In your "App_LoadingStatus" block you wrote postReady(e.origin) but your handler argument is event, not e. Use postReady(event.origin) (or capture it once into a codeOrigin variable).
Finally, ensure your FastAPI PostMessageOrigin matches that exact origin string (including protocol, IP, port).
@coolio i would highly recommand to explore the SDK examples repository. That might help with your case.
It looks like there is some syntax errors which is causing the issues