How to add a link to start a file download in a Rails Facebook canvas app - ruby-on-rails

In our Rails app that runs in Facebook canvas, we have a workflow where a logged in user can build a document and then download it.
When the file is ready we show a link to it. This is just a Rails action that renders using send_file in dev or head (with proper NGINX config) in production. This part works fine.
In order to have the file start downloading without opening a new browser tab, we had the link target an empty iframe.
This was working, but a while back, presumably due to a security change by Facebook, our link stopped working. The JavaScript errors show:
Refused to display document because display forbidden by X-Frame-Options.
Users can still open the link in a new tab and it will download the file and a quick fix is to make the link open a new browser tab, but that isn't as good of a user experience.
We tried changing the X-Frame-Options in the headers and/or using meta tags, but this is canvas (running in an iframe), so that just stopped those views from displaying.
I also tried this form solution, but it didn't do anything (I could have been doing it wrong).
Is there any way we can build a button or link that will start the file download without opening a new browser tab?

Do you need to set the target at all? With no target set would it not trigger a file download popup in the browser, but leave the current browser window/tab on the same content?

Related

React PWA Image Upload in Mobile Safari breaks application?

We were surprised we didn't find any mention of this anywhere online, so we're posting here in hopes we find a solution.
Using an iPhone with mobile safari is when we hit this issue running the 2 easy to follow tests below, one works, one doesn't.
Here is the link
https://pwa-react.netlify.com/
Here are the 2 tests we run (both listed in the link), one works when not in PWA mode, and the other fails when in PWA mode.
Test #1: Works Perfectly (Expected Behaviour)
Visit https://pwa-react.netlify.com/ from iPhone in mobile safari
1. Make sure you have google drive on the phone but not logged in.
2. Click "Choose File". It will show you the list of options to choose from.
3. Click "Browse" to look for the photo.
4. Click "Cancel" and you're back here.
5. Click "Choose File" it will still show you the list of options to choose from.
This works perfectly in mobile safari but NOT in PWA mode below.
Test #2: Does NOT Work (Unexpected Behaviour) (PWA)
Visit https://pwa-react.netlify.com/ from iPhone in mobile safari, hit the share
button, then add to home screen. This will add the PWA app on your phone. Open App.
1. Make sure you have google drive on the phone but not logged in.
2. Click "Choose File". It will show you the list of options to choose from.
3. Click "Browse" to look for the photo.
4. When it shows you the Google Drive logo with Sign In, double click the home
button, then go back to the PWA.
5. Click "Choose File" it will NOT show you the list of options to choose from.
This is now 100% broken.
The ONLY way to fix it is to go to Settings>Safari>Clear History and Website Data (all the way down)
How can we fix this so when the user hits "Choose File" it shows the list of
options to choose from in the PWA?
Screenshot #1: These are the options that appear in Test #1 and stop appearing in Test #2
Screenshot #2: This screen allows us to cancel in Test #1 but it disappears in Test #2
Any idea how to get Test #2 to work by allowing us to choose the upload options like in Screenshot #1 without breaking the app and having to go to safari settings to clear history and website data for it to function again?
PS - Here is the repository file pwa-react/src/App.js
We were facing almost exactly the same issue in our PWA, so first, off I want to thank you for helping us narrow down the cause.
After reviewing the iOS PWA lifecycle (article here) and a couple maddening hours of trial and error I was able to figure out a solution that is semi-acceptable.
My guess at what is happening when you leave the app mid-upload (Test #2) is that there is some internal context in how iOS handles PWA's that is not being reset, so when you go back and try to upload a file again it thinks that the upload dialog is already open.
The article mentions that opening external links without target=_blank will cause the PWA context to be deleted, so when the in-app browser closes, the PWA page reloads in the standalone window. I thought that might reset the "detached upload" context, and it ended up working.
So I created a page hosted on another domain, and linked to it below our upload button in the PWA:
// not sure the target={'_self'} is necessary but not risking it
<a href={'https://externalDomain.com/reset'} target={'_self'}>
Having Issues? Reset Upload
</a>
This works decently well, minus one issue. When you click this link it opens the in-app browser, but there is no "Done" button or navigation tools for the user to know how to exit. Linking back to the PWA does not work, because iOS detects that and does not reset the app context. What I did notice was that if I navigated to another page from the first external page (I originally just tested this with google.com), the "Done" button would show up, making it obvious how to exit.
With that knowledge, I guessed that you could probably just do window.history.pushState to achieve the same effect, which works. My final solution is below. It causes the entire app to reload when the user presses Done from the in-app browser, but that's far better than having them re-add to the home screen in my opinion.
const Reset: React.FC = props => {
React.useEffect(() => {
// Redirect any wayward users who find this page from outside the PWA
if (!window.matchMedia('(display-mode: standalone)').matches) {
navigate('/');
}
// push an additional page into history
const newUrl = `${window.location.href}?reset`;
window.history.pushState({ path: newUrl }, '', newUrl);
}, []);
return (
<Grid container>
<ArrowUpIcon />
<Typography variant={'h5'}>Press done above to return to App</Typography>
<Typography variant={'body1'}>Sorry for the inconvenience!</Typography>
</Grid>
);
};
Hope this helps! Would love to hear if it works for you.
Edit After Production Testing:
An additional important note is that your "reset" page must be on a completely different domain for this to work. Ran into this today in production, because our reset page was on a subdomain with the same root as the PWA, iOS was not resetting the entire PWA lifecycle.
SUMMARY
Key Issues:
Leaving an iOS PWA while any of the "file upload" dialogs are open ('Take Photo', 'Photo Library', or 'Browse') breaks the iOS PWA lifecycle.This breakage makes it impossible for the user to open any "file upload" dialogs when clicking on a file input.
In order to fix this issue, the PWA context must be completely reset.
It seems that the only ways to reset the PWA context are to restart the phone, delete the app and re-add it to the home screen, or to open an external link.
When opening an external link, the "Done" button that closes the iOS PWA embedded browser will not show on the initial page. The user must navigate to an additional external page in order for the "Done" button to show.
External links do not trigger a reset of the PWA context reset when they have target="_blank".
Solution:
In order for the user to be able to upload files again, the PWA context must be reset. The easiest way to do this (in my opinion) is to ask them to open an external link.
(In PWA): Present a link to the user to fix the fact that the upload dialog is not showing. The link destination must be a completely unrelated domain (not a subdomain) and must have target="_self" (issue #5).
(External Page): Once the user clicks on the link and the external page opens, there will be no visible way to leave the page (issue #4). To resolve this, you can use history.pushState to simulate navigating to an additional page.
(External Page - Bonus): To make it clear to the user that the issue has been resolved, add an arrow in the top left pointing to the "Done" button (as shown in my screenshot).

apple-app-site-association correct configuration

I am trying to implement an associated domain for an app I'm working on. So far, I have:
Enabled the Associated Domains capability of the app
Added all required domains with applinks:www.domain.com
added an apple-app-site-association file to the root of my server, and when that didn't work also to the .wellknown on my server
This didn't work. When I go to the page that is supposed to open a view controller in my app, it doesn't redirect but only show the banner instead. When I tap the 'Open' button on the banner, however, the right view controller in my app is shown.
Then:
I tried changing the mime type of the file, from application/json
to application/pkcs7-mime.
I verified there is no .json extension
I verified that my server returns a valid response code (200), doesn't redirect, provides the file over https (I havent encrypted
it).
I verified the file has valid JSON.
I even checked in my browser whether it finds the file and it does.
Finally, I have copy-pasted the URL in notepad on the iPhone, long-pressed it and the option 'Open in App' appeared.
Nothing appears to be wrong, yet iOS doesn't link to the app in any circumstances, it only shows the Banner.
What am I missing here? How can I get safari to open my app instead of just showing the banner?
P.S. please note: The website of this project is an asp .net application

iOS WKWebView Handle File Download

I am facing the following problem:
In a web interface, file downloads are triggered with an anchor tag, like this:
<a href="/bla/blabla" download>..</a>
While Safari browser can handle this request and open a dialogue to handle the file, WKWebView treats this just as an ordinary link and does nothing with it. I want to be able to get the file handler dialogue that is normally there when using Safari.
Right now there are 2 problems and I do not see an opening there yet:
I can not detect a click on the element as it is treated just as a normal link. And I can not rely on the URL parameters to detect if it is a file since that is not constantly true.
Even if the URL is defined as a one leading to a file, I can not pass it to Safari since it does not share session info and cookies with my app's WKWebView.
Therefore, I would like to know if there is any opening in handling files in iOS WKWebView. Thank you.

Chrome refuses to load some PDFs in the browser

Our web application lets users upload forms in pdf format (which are then stored in a Windows Azure Blob) and also lets them view them afterwards. What we want to is embed the pdf in a lightbox sort of thing. This is working totally fine in firefox once something like Acrobat Reader is installed but Chrome does absolutely nothing with it.
Even before getting to the embed part, just opening it in a tab doesn't work in Chrome. Entering the url in firefox works fine and it will ask if you want to save or open in Acrobat Reader. Opening a new tab in chrome and trying go to the url does absolutely nothing. The page just stays a blank white, and the name of the tab remains as 'New Tab'.
I checked what was going on in the Network tab of the browser console, and all I see is a supposedly successful GET call (code 200) but the status of it is cancelled.

Links in remote JQueryMobile sites in a PhoneGap app open safari

I'm having quite a peculiar problem with PhoneGap and JQuery Mobile, using the latest versions of both frameworks as of this writing.
My phonegap app has some pages 'local' to the app, and other pages that are loaded directly from a remote site. Going between the local and remote pages is fine (there is no transition but that can't exactly be helped). However, once I'm on the remote pages, any link I click on the remote pages opens Safari with the page I requested. This is not desirable functionality, as I would like it all to be within the UIWebView, and none of my links are marked with anything special that would cause Safari to open.
It gets weirder. If I then switch from Safari back to the program, the remote page I requested appears in the UIWebView, however pressing the back button leads me not to the first remote page, but the first local page.
The phonegap app right now is quite bare, very close to the default except with JQM css + js loaded. This happens even if I create a simple test app that has one local JQM page, one remote JQM page and then a remote page that is linked to from a JQM remote page.
I'm stumped. What's going on here?
The default behavior for PhoneGap is to open external links in Safari unless they are added to the ExternalHosts property in PhoneGap.plist.
Try adding the external hosts and PhoneGap should behave correctly and load the external locations inside of the application.
(source: tumblr.com)
Here also is a post about using iFrames and ExternalHosts that could be of some help as well.

Resources