Open jamiemtdwyer opened 6 years ago
We should update this asap
Take a look at my module which is a drop-in solution for this. It uses the postMessage
solution.
Thanks for that @marekweb.
I think that ideally, we'd make this available in such a way that it's not specific to OAuth redirects, but rather give consumers a method to invoke (or perhaps an additional method) to perform a full-page redirect any time it's needed – the only other scenario I can think of off-hand would be a redirect to the RecurringApplicationCharge acceptance screen.
Hi, This is indeed interesting and having a specific method will be useful to bypass using window.top.location.href 'hack'. Attaching the code as we are using at the moment in a selection plans page which we need the user be taken to the window.top.location +'/client/plan-select' as theres the express router listening for the method with the logic for the charge acceptance screen (just in case its helpful to show how real-world shopify apps are at the moment solving this missing functionality).
<CalloutCard
title={'Trial'}
primaryAction={{
content: '3-Day Trial: $0,00',
onAction: () => window.top.location.href = '/client/plan-select?plan_name=trial'
}}
>
The problem with window.top.location
is that there is a discussion around this not being supported in future versions of Chrome, in order to prevent cases where annoying advertisements can redirect the parent window. This change was originally targeted for Chrome Canary (v65), but I believe the Chrome team has held off on this. Based on what I've read / heard, it might be included in the final release version of Canary as an optional user configuration.
Sorry I don't have any links handy at the moment pointing to the discussions from the Chrome team, but I'll try to grab them when I have time.
@jamiemtdwyer Good point about other the use cases for the redirect. The function in shopify-express-oauth-redirect
which does that is called createRedirectBody
and it generates a redirect for any arbitrary URL.
Here's a usage example.
const createRedirectBody = require('shopify-express-oauth-redirect/create-redirect-body');
const redirectBody = createRedirectBody('https://example.com/arbitrary/url', 'shiny-trinkets.myshopify.com');
res.send(redirectBody);
Here is the contents of redirectBody
in this example. The implementation is based on the same approach as in inshopify_app
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<base target="_top">
<title>Redirecting...</title>
<script type="text/javascript">
// If the current window is the 'parent', change the URL by setting location.href
if (window.top == window.self) {
window.top.location.href = "https://example.com/arbitrary/url";
// If the current window is the 'child', change the parent's URL with postMessage
} else {
normalizedLink = document.createElement('a');
normalizedLink.href = "https://example.com/arbitrary/url";
data = JSON.stringify({
message: 'Shopify.API.remoteRedirect',
data: { location: normalizedLink.href }
});
window.parent.postMessage(data, "https://shiny-trinkets.myshopify.com");
}
</script>
</head>
<body>
</body>
</html>
Logging this now while it's fresh in my mind
https://github.com/Shopify/shopify-express/blob/master/routes/shopifyAuth.js#L37-L47
This code is at risk of breaking in a future version (65?) of Chrome, where Chrome will prevent redirects in the parent window.
The solution is to use a
postMessage
to the Shopify EASDK in order to perform the redirect. See the following example fromshopify_app
:https://github.com/Shopify/shopify_app/blob/3fb589d71bc03a11a8bb48bf87e613f6ce0210ea/app/assets/javascripts/shopify_app/redirect.js