browser downloads rails response as a file - ruby-on-rails

I have been fiddling with rails apps for a while and I sometimes see this behavior on Safari (could be on other browsers as well, not sure) where the browser downloads the response as a file instead of rendering it in the browser. I wonder why that is.
The last time it happened made me decide to ask on stack overflow. My current setup is a very basic rails app that implements devise and I get a file named 'sign_in.admin' with just the following content:
You need to sign in or sign up before continuing.
I know that string comes from the devise locale and is supposed to be rendered with a layout, but the browser just downloads it as a file as if I chose to 'Download linked file as...' It's happened to me before where instead of rails routing me somewhere it downloads a file. Can somebody explain why my browser sometimes does that? I have all the latest updates.

Related

Webpack url-loader PDF data URI link for Vue site stops working in iOS 14

I have a Vue.js website with a PDF file which is included in my ultimate javascript bundle via webpack. (It's my CV.) The following build and delivery process has worked perfectly fine for me since 2017, but suddenly stopped working in iOS 14:
Build the PDF with LaTeX.
Use webpack's url-loader to include the PDF in my webpack bundle as a base64 data URI.
Load that URL into a vuex data store, and then just deliver it as a link when clicked.
For the last three years, this has worked fine: I've been able to click on the link and get a working PDF. It's been kind of random and platform-specific whether the PDF opens in-browser or shows up in a download folder, and whether it gets the filename I've asked it to get or not, but, well, that doesn't matter to me. And the core functionality of click the link and get the PDF has worked on every browser and every platform I've ever tried it on.
All of a sudden, with iOS 14, it's stopped working. Now, when I try to activate the PDF link in iOS Safari, nothing happens at all. When I do it in iOS Chrome, it produces a little popup claiming it downloaded a document, but nothing seems to actually be able to open the document. And when I do it in iOS DuckDuckGo, it just displays the base64 data URI in the address bar.
Interestingly, if I take the dataURI that DDG displays in the address bar and copy and paste it into Safari or Chrome on iOS, it actually displays my pdf. So the browsers still have the capacity to display a PDF from a data URI. It just doesn't want to do so from my link.
And my site still works as expected on the desktop. Including in Safari on the desktop. Also, it still works on my wife's phone (she's still on iOS 13). So this is clearly something Apple changed in iOS 14. But what? And how to get my site working again?
I'm guessing that Apple has changed the behavior of the renderer in iOS in some fashion to cause it to break across browsers but nowhere else (since browsers in iOS are all still required to rely on webkit, right?)
This is a pretty important feature to me. I made this decision deliberately for perceived performance---combined with pre-rendering, everything on my site, including the PDF, loads very close to instantly from the user perspective. So I'd really like to keep it.
I'm using Webpack 2.6.1 and Vue 2.3.3. This is a stable build that has been working flawlessly for three years, so I haven't felt the need to update anything except for security updates.
After searching around, I did find this Apple dev discussion which suggests that in iOS 14, Apple newly blocks redirects to data URIs. But I'm not doing a redirect, I'm actually navigating directly to the URI through a link. And the linked discussion suggests that the newly banned behavior just brings Apple in line with what other browsers already ban---but my code works in every other browser, so that can't be it.
Relevant code, to the extent it matters (though it's so basic and obvious that I doubt a simple code fix will be the answer here):
from my webpack.base.js:
{
test: /\.(pdf)$/,
loader: 'url-loader'
},
from my vuex store, in state.js
import cvURL from './assets/pdf/gowdercv.pdf';
from the component containing the link that points to PDF:
<p><a :href="cvURL" download="gowdercv.pdf"><img src="../../assets/icons/file-pdf.svg" class="cvicon"> Download in PDF</a></p>
which is loaded as a computed property to the component, i.e.,
computed: {
cvURL: function(){return this.$store.state.cvURL;},
Does anyone know how to get functionality back in iOS? Is there a workaround built in recent versions of webpack or vue for this? Thanks!
Update: after some help off SO, an acquaintance turned up this similar problem, which also came up with a solution: turning the base64 URI into a blob and passing that data url. Which also solves my problem. Though that SO doesn't have an accepted answer, so I can't vote to close my own question as a duplicate, alas.

First attempt at file download does not work. Need to click link twice and it works

I am having a really weird situation and would appreciate any help that can be provided.
My setup is pretty simple. I have an ember app that communicates with a Rails backend. I hit a certain route and a spreadsheet report is generated and placed in the public folder of the rails app. So far so good.
The rails backend then sends a response with the path to the file to the front-end that I place in a href that people can click on to download the file. This is where the weirdness happens. The first time that the link to download is clicked, I get a 404. What's weird is that if I click the link again or copy and paste the url into the address bar, the download works. No matter how I attempt to download the file, the first attempt always fails and all subsequent attempts succeed. I even set it up so that on one click I try to download the file twice and the first attempt fails and the second one works. This is definitely not ideal though.
edit: Also ... This only happens in production. In development, the download works perfectly fine.
I have no idea what the issue is and would appreciate any help in this.
Thanks

Application cache: strange behaviour on iPad

I'm making a website where a user can say which items he wants to cache. Based on this, a manifest file is generated. By doing this the user can still browse in the website when he is offline. This is all working fine in google chrome. But on iPad it's not working as it should.
Sometimes things get cached sometimes not, not even the pages i visited.
We have been testing with 2 iPads all morning, but we haven't been able to get the same result on both iPads. Even if we do exactly the same, we sometimes get different results.
So what we do:
turn WiFi on
browse to the website
make some settings so some pages/images/... are added to the manifest file
turn WiFi off
go back to safari refresh/browse to pages that should be cached.
Sometimes on one iPad (this is an iPad 1) it works exactly as it should, but sometimes it doesn't work at all.
On the other iPad (this is an iPad 2) it never works completely as it should. Just some random results.
It also looks like the results are different when we completely shutdown safari, and then clear the cache and then do the whole process of downloading and caching stuff...
Somebody can help me with this problem? It's a real pain in the ass at the moment... :(
Open web server (IIS)
Select website
Open MIME type
Add or edit to text/cache-manifest
Reset iis at command prompt iisreset
It works for me.
I've encountered some problems as well with ipad caching.
MIME type of the manifest file is not set right due to windows hosting. The standard MIME type on a windows server is "application/x-ms-manifest". This was created when the ClickOnce applications came to life. The MIME type that is necessary to work on safari is: "text/cache-manifest"
Cache size is too small on ipad (you should get a warning to enlarge it)
the Ipad needs time! I've noticed that the cache is not filled when you see all assets or when the website is "loaded". Give it twice the normal time to load before you place the website to your homescreen.
Cache of the cache :) The iPad only reloads the files when the modified date on the server is changed. So when you really want to test, clear all cache on the iPad, remove the link on the homescreen and upload all your files again.
Conclusion: Time consuming!
Hint: Turn on the debug console in safari on your desktop or iPad. It gives a fair idea if you did something wrong or if it is a cache problem on the iPad.
It looks like the problem didn't have anything to do with the application cache. It was somehow a problem with the cookies/the way i was dynamically building the manifest file.
I'd like to slightly echo Pieter-Paulus Vertongen, I had a similar experience with Windows hosting.
According to the debugging console in Safari, the mime type for the manifest file was being misread and nothing was being downloaded as a result.
I copied all of my files, including the .htaccess file, over to a linux server without changing any content within the files...and then the caching worked beautifully.
So yes, it's possible this may be an issue of where the files are hosted. Use the debugging console and Jonathan Stark's code to find out:
http://jonathanstark.com/blog/debugging-html-5-offline-application-cache?filename=2009/09/27/debugging-html-5-offline-application-cache/

Installing applications OTA

I have a system set up to download jad files on users' Blackberries, but it only works intermittently, and seemingly randomly. If the user clicks on the link within their BlackBerry browser, 95% of the time on the first try an error message will pop up saying there was an HTTP 500 error (which our server never returns).
Viewing the details of this message within the blackberry browser, it says nothing but java.lang.nullpointerexception which, again, could not have come from our server (running apache/php).
However, if the user clicks on the link a few more times, or navigates away and goes back to that page, it suddenly works. No change on the server, it just shows the application install screen. Unfortunately, this doesn't always work; sometimes the error 500 just keeps showing up.
The link is rather long (containing an sha hash as a token as part of the URL), but I would think that a long URL would either always be broken or always work, not work intermittently.
The link uses a php script to download the jad and cod files. Linking to the files directly rather than using the script seems to work more often (I haven't determined if that also ever has an error 500 or not), but I can't find any issues with the headers. The content type is set correctly and, like I said, if the headers were an issue, I'd think it would either always work or always break.
Any clues?
You may be able to shed some light on the problem by looking at the event logs, which you can get using JavaLoader:
javaloader -u eventlog > event.log
Search for NullPointerException within those logs and you'll be able to see what's causing it.
I can't explain the intermittent behaviour, but I had a similar situation where I was getting the java.lang.NullPointerException in the browser details. Unfortunately, the Event Log (as dumped by javaloader.exe) or by viewing on-device using Alt-L-G-L-G didn't show the exception.
(I'm using bb-ant-tools and JDE 4.6.1.) When the signature tool ran, I noticed that there were two .cod files being signed and I can see both of them inside the .jar file the compiler creates. But the output written was a single .cod file of size 92306 bytes that was not a .zip of smaller .cod files. The compiler somehow was not able to create a .cod that contained siblings. For comparison, compiling the project with JDE 5.0.0 created sibling .cod files that were able to be loaded over OTA.
My project included an .mp3 file of 53542 bytes which I happened to not require. After removing it, the 4.6.1 compiler outputted a single .cod and I was able to successfully download it via OTA.

Ionic 3 PWA not updating smoothly on iOS

We built a PWA with Ionic 3, which is a multiple page application. We host this on a linux server with nginx and use Laravel as a backend
The situation
We have seen that a update to a PWA is not always instantly, our client requested that if we released a update this would happen instantly and automatically.
What we tried
File based caching:
Our first thought was to use the concept of (old fashioned?) cache busting, so when building the app we use a random hash string in the filename. This ended up causing a major issue: Some PWA’s seem to hold on to the old index.html. In our access log we can see that old files get requested. The result being people will see a white screen after the splash screen. The only way for them to fix it is to reinstall the PWA completely.
Url based caching:
We devised a new plan: instead of using random hash string in the filename we moved in to the folder name. The request path would look like this: ./build/98312uj91eh9u2e/vendor.js. With NGINX we remove the hash and serve the same file, so it will return the the file from this path: ./build/vendor.js. This caused another issue where files would be mismatched. So some user would have parts of the old version and parts of the news versions which caused a lot of random issues.
Hosting multiple versions hoping they would update:
This pretty much did nothing other than creating lot of confusion. because some PWA’s would never update some people would be stuck on a old version and not see the new features.
Our current idea
Instead of using a static html file we are thinking of using javascript to make an API call to the backend of the PWA. Which will return a string with the current version of the PWA. This version will be the random string contain within the file names. This way, regardless of index.html updates, the content well be dynamic and not cause issue before description issues.
So what is the question?
Is it a good idea to make use of the concept where we would use JavaScript for making an API call or would this cause other issues we have not thought about yet.

Resources