Forms in iframes... or not?

Vote:
 

Hi All,

Hope you are staying safe.

I'll provide some background to what I'm trying to do, just incase I'm focusing on solving the wrong problem!

Background:

We recently implemented a caching strategy with the help of EPiServer's own Johan Antila. It's a full page cache based on David Knipe's caching with Visitor Groups, in which Johan modified the solution to also work with A/B testing. And it's awesome, we saw our TTFB drop from around 1 - 2s down to 200 - 500ms when the cached version of a page is requested. We are super happy, but then we discovered we had overlooked Forms! (how could we!?!) Antiforgery tokens and caching don't mix :/

I quickly modified the implementation to not cache a page if there was a form present, but a significant portion of our pages have a form on and it's ruining the good vibes. On top of that, we know that this is only a temporary solution until we can work out how to handle forms. Maybe some kind of donut hole caching mixed in with what we have? Or forms in an iframe?

My journey so far:

Given how close we are with the caching implementation, I've shied away from any donuts and I guess I fear that I'll end up going down that road eventually. But not before I've exhausted the iframe possibility.

And I feel like I've got quite far with an iframe solution. I've created an iframe block type. I've created a new form container page type to only hold a single form, and restricted the iframeblock to only reference a single one of these new formcontainerpages. The formcontainpage has it's own layout so I'm able to strip out any calls to the main site's javascript files and redundant meta tags etc and the result is a page containing just a form being loaded inside an iframe. The parent page is cached nicely and the iframed form container page is not, the antiforgerytoken stuff is all happy and forms are basically working.

Gotchas:

We like a thank you page! When users complete a form they are generally taken to a thank you page and we use that hit for conversion tracking etc. But no one wants to see the thank you page loaded just inside the iframe... I can of course write some js to use the MutationObserver api to detect when the iframe changes url and use that to redirect the parent page of the iframe, but this of course results in two hits to the thank you page and that just won't do.

For seemingly obvious security reasons, you can't use a window's onbeforeload event to grab the intended destination page and stop the iframe from requesting the thank you page before redirecting the parent page.

I thought perhaps I could hook into FormSubmissionFinalized event from Forms and somehow see the final destination url there, but I can't even see that firing even though the submission data in the CMS shows as finalized. But given the data submission stuff is all handled on the server, that was probablly a silly idea in the first place.

So I began wondering about custom actors. Could I write a custom actor which would optionally overwrite the redirecturl functionality of the forms and somehow hook that into the iframe to post a message to the parent and force the parent page to redirect instead?

My question(s):

So finally to my questions. Is that possible? How would that even work?

I've been looking at the decompiled code from Forms and from Forms.Demo and I can't quite see yet how that is implemented. I'm guessing that there'll be some code doing something like RedirectToAction(RedirectUrl? + FormSessionData) and I'd need an actor to overwrite that method. But then what? a custom action method which passes the data to a script I can then use in the iframe to assign window.top.location.href ?? I'm not really sure.

Am I barking up the completely wrong tree? Is the approach I am trying to take just not possible?

If anyone can help, I would be so so so grateful!

All the best,
Alex

#225967
Jul 31, 2020 13:20
Vote:
 

... it's setting target="_parent" to the <form> isn't it...? no it's not. not setting it to _top either. lol once again, I thought I had it.

I also found where RedirectToUrl is in forms. It's buried deep in EPiServer.Forms.Core.Internal.DataSubmissionService redirectUrl used as argumenment for this.BuildReturnResultsForSubmitAction() so without forking EPiServer.Forms and rewriting the internals I don't see how I'm going to do that ha ha ha even if I could!!!

#225969
Edited, Jul 31, 2020 15:20
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.