Downloading PDF files on IOS while using Angular often results in the PDF opening in the same

I'm currently utilizing file-saver within my Angular application to retrieve a PDF generated from the backend. The library functions smoothly on desktop and Android devices, but I'm encountering issues with downloading files on iOS. Contrary to what is mentioned on the GitHub page, file-saver does not open the blob in a new window; instead, it opens on the same page (which is undesired). Interestingly, it works seamlessly on Safari by prompting a download dialog without opening the file, but fails on other browsers like Opera, Firefox, and Chrome.

I've experimented with various alternatives such as file-saver, downloadJ, creating an anchor tag with the download attribute, utilizing the application/octet-stream mime-type, and exploring different solutions found online. Unfortunately, most of these methods either do nothing or result in the PDF displaying on the same page rather than initiating a download or opening in a new tab (as specified by file-saver for iOS).

As the PDF is being generated in a Google Cloud Function, I am wondering if there might be a way to bypass the client-side processes and have the browser directly download the file from there.

Is there any alternate approach to downloading PDFs on mobile iOS devices (such as implementing a service worker)?

Appreciate any input or suggestions in advance.

Answer №1

Solution that adheres to the latest Chrome specifications can be found here

Utilizing Vanilla JavaScript

public static downloadFile(url: string): void {
     const xmlHttp = new XMLHttpRequest();
     xmlHttp.onreadystatechange = () => {
       if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
         const blobUrl = window.URL.createObjectURL(xmlHttp.response);
         const e = document.createElement('a');
         e.href = blobUrl;
         e.download = blobUrl.substr(blobUrl.lastIndexOf('/') + 1);
         document.body.appendChild(e);
         e.click();
         document.body.removeChild(e);
       }
     };
     xmlHttp.responseType = 'blob';
     xmlHttp.open('GET', url, true);
     xmlHttp.send(null);
   }

If you're working with Angular, consider this approach.

async downloadBrochure(url: string) {
    try {
      const res = await this.httpClient.get(url, { responseType: 'blob' }).toPromise();
      this.downloadFile(res);
    } catch (e) {
      console.log(e.body.message);
    }
  }

  downloadFile(data) {
    const url = window.URL.createObjectURL(data);
    const e = document.createElement('a');
    e.href = url;
    e.download = url.substr(url.lastIndexOf('/') + 1);
    document.body.appendChild(e);
    e.click();
    document.body.removeChild(e);
  }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Determine using Lodash whether there is an object in an array that matches the ID from a separate array

There is a user array defined as follows: var users = [{ id: 1, name: 'ABC', isDisplay: true }, { id: 2, name: 'XYZ', isDisplay: true }, { id: 3, name: 'JKL', isDisplay: true }]; Additionally, there is another arra ...

Trigger an endless loop upon window.onload event

Every now and then, when a user opens the page, it starts flickering and resizing itself. After checking the log, it appears that the submit function is being called multiple times, but I can't reproduce this issue in my own environment. Is there som ...

Tips for loading and updating data simultaneously in VUEJS from a single input

Currently, the data is displayed in a span tag with an input for updating it Is it possible to fetch data from an API, load it into an input field, update the input with new information, and send it back? What are the best approaches for achieving this? ...

What is the best way to iterate through an array within a class in Angular 2?

I am trying to iterate over an array named data, within another array containing 'champions'. Can anyone provide the correct syntax for this? I can successfully loop through all the champions within my IChampion interface, but I'm having tro ...

NextJS 13 causes tailwind to malfunction when route group is utilized

I've encountered an issue in my NextJS 13 application where Tailwind classes are no longer being applied after moving page.tsx/layout.tsx from the root directory to a (main) directory within the root. I suspect that there may be a configuration that i ...

Error in GraphQL query: specified argument is mandatory, yet not supplied

I recently started learning about graphql and encountered an issue with my query. Here is the code I am using: { product { id } } "message": "Field "product" argument "id" of type "String!" is requir ...

Changing the font family for a single element in Next.js

One unique aspect of my project is its global font, however there is one element that randomly pulls font families from a hosted URL. For example: https://*****.com/file/fonts/Parnian.ttf My page operates as a client-side rendered application (CSR). So, ...

The Cross-Origin Resource Sharing request using the PUT method has been denied due to restrictions set by the

I am currently using CORS requests to communicate between my client and server located on different domains. I have configured my Apache HTTP server to use SSL in the following manner: // Utilizing AJAX withCredentials=true (sending cookies, allowing SSL ...

performing an AJAX request to the controller method in a Rails application

I am currently facing an issue with making an ajax call to my controller class PatientRecordController < ApplicationController def export .... end end Within my javascript file, the code snippet is as follows: $(document).ready(function(){ ...

Node.js process.exec() function allows you to asynchronously spawn a subprocess

After writing the code, I ran it and found that the terminal was unresponsive with no output, causing the program to be stuck. var util=require('util') var exec=require('child_process').exec; exec('iostat 5',function(err,stdo ...

Substitute dynamic Angular expressions with fixed values within a string

Inside my angular controller, I am defining a stringTemplate containing expressions like "{{data.a}} - {{data.b}}". Along with that, I have an object named data with values {a: "example1", b: "example2"}. My goal is to find a way to replace the dynamic ex ...

Updating the positions of Mesh objects in Three.js asynchronously

I'm currently working on a Three.js application where I am creating a grid to display various objects. These objects are rendered on the grid based on their positions, which are obtained from data fetched from a REST API that I poll every 300 millisec ...

What is the process for destructuring an interface in TypeScript?

My request is as follows: const listCompartmentsRequest: identity.requests.ListCompartmentsRequest = { compartmentId: id, compartmentIdInSubtree: true, } I want to shorten the long line identity.requests.ListCompartmentsRequest. I'm looking for ...

Modify the class of the dropdown and heading 2 elements if they meet specific conditions using Animate.css

Is it possible to add a class using jQuery when two specific conditions are met? 1) If the dropdown selection is either "acting" or "backstage" 2) If the membership status is set to "Non-member" If both of these requirements are fulfilled, I would like ...

Ways to extract only numbers from a string

I have encountered a frustrating issue in VueJS: I am receiving an object with the following structure: { "description": "this is our List.\n Our Service includes:\n-1 something\n-2 something else\n and another thing\n"}` My dile ...

Sharing Pictures and Messages using angular, express, and multer

Struggling with posting images and text to the server while self-learning Angular. The backend works fine in Postman testing, but fails when working with Angular. Here is the code snippet I have been using: upload.component.html <form [formGroup]="upl ...

When attempting to load a page in Mozilla, the initial DIV code fails to load

When trying to load a page in Mozilla, the first DIV code is not loading. I attempted to load HTML inside using: <div id="mainContent"></div> with the following call: if (destinationURL != null) { $.get(destinationURL, function(data) { ...

Managing environment variables in server-side rendering using Angular Universal

Currently, I am integrating SSR into an existing Angular project. Previously, with Client Side Rendering CSR, I utilized the global variable window to manage ENV VARS for various deployments and continuous integration/continuous deployment CI/CD purposes, ...

Oops! Next.js Scripts encountered an error: Module '../../webpack-runtime.js' cannot be located

Looking to develop an RSS script with Next.js. To achieve this, I created a script in a subfolder within the root directory called scripts/ and named it build-rss.js next.config.js module.exports = { webpack: (config, options) => { config.m ...

Devising a method to display configurable products as related items along with their customizable options in Magento

I am in the process of creating an e-commerce website using Magento for a client. The issue I am facing is that when I include a configurable product as a related item, it displays the product but without a checkbox. From what I have researched, Magento do ...