Saving base64 encoded pdf on Safari

I am facing an issue with a POST call that returns a base64 PDF. The problem arises when trying to convert it to a Blob and download it using Safari browser. This method works perfectly in all other browsers.

openPdf = () => {

  const sendObj = {
    fakeValue: 'test'
  };

  axios.post('https://fakeendpoint.com/create-pdf', sendObj)                
    .then((res) => {
      const base64URL = res.data;
      const binary = atob(base64URL.replace(/\s/g, ''));
      const len = binary.length;
      const buffer = new ArrayBuffer(len);
      const view = new Uint8Array(buffer);

      for (let i = 0; i < len; i += 1) {
        view[i] = binary.charCodeAt(i);
      }

      // creating the blob object with content-type "application/pdf"
      const blob = new Blob([view], { type: 'application/pdf' });
      const url = URL.createObjectURL(blob);

      const a = document.createElement('a');
      document.body.appendChild(a);
      a.style = 'display: none';
      a.href = url;
      a.download = 'Test.pdf';
      a.target = '_blank';
      a.click();
  });
}

Any suggestions on how to make this function properly in Safari?

Answer №1

It appears that Safari is not adhering to the standards for the a tag. A previous discussion on Stack Overflow (found at this link) seems to have pinpointed the issue. According to comments in the linked post:

It's important to note that specifying a target attribute in Safari might override the download attribute, unlike in Chrome, Firefox, or Opera.

One possible solution would be to remove the line a.target = '_blank' from your code and test it again. This adjustment should resolve the problem!

However, if you rely on opening the link in a new tab, it may require further exploration for an alternative method.

Answer №2

During my testing, I discovered that this issue only arises when the PDF file is too large, and specifically on mobile Safari. My hypothesis is that it has to do with the length of the URL.

An alternative solution could be removing the target="_blank" attribute, but one downside to consider is that users may lose their previous page state if they click the "back" button.

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

Guide to retrieving PDFs and images from a Spring Application as an API response and manipulating the data using JS/React

For my current project, I am working on a Spring Boot and React application where I need to create an API that takes the file name as input and returns the file content in Java/Spring Boot. The goal is to display the content in a new browser tab. Below is ...

Managing data from two tables in Node.js with ejs

I have a question regarding my node.js project that I need help with. As a beginner in this field, I believe the answer may be simpler than anticipated. In my code file named index.js, I found the following snippet after referring to some online documenta ...

Using JavaScript, concatenate text from each line using a specified delimiter, then add this new text to an unordered list element

I am looking to extract text from named spans in an unordered list, combine them with a '|' separating each word within the same line, and append them to another ul. Although my code successfully joins all the words together, I'm struggling ...

What are some ways to postpone the execution of a function in React or NextJs?

How do I automatically redirect to the home page after 5 seconds of accessing a page in NextJS? I attempted to achieve this using the following code: useEffect(() => { const timer = setTimeout(() => { redirect('/home') ...

Attempting to load an image through an AJAX Request may prove to be unsuccessful

I am facing an issue with using an AJAX request to load a gif image from the following source: Despite my attempts, using the response on the image source like this: $('#cat-thumb-1').attr('src', 'data:image/gif;base64,' + d ...

How can you personalize the dropdown button in dx-toolbar using DevExtreme?

Currently, I am working with the DevExtreme(v20.1.4) toolbar component within Angular(v8.2.14). However, when implementing a dx-toolbar and specifying locateInMenu="always" for the toolbar items, a dropdown button featuring the dx-icon-overflow i ...

The Firefox extension is unable to activate any click events

Currently, I am developing a Firefox add-on with the goal of automatically filling in login form fields and submitting the login. For each website, I have access to various identifiers such as ids, classes or xpath, depending on what is provided by the web ...

Creating dropdown menus dynamically and populating them based on the selection made in one dropdown menu to determine the options available

Looking to enhance the filtering options in my ngGrid, I stumbled upon the concept of Filtering in Ignite UI grid and was impressed by its functionality. I am now attempting to implement a similar feature in AngularJS. Breaking down the task into 4 compon ...

Can a single camera be utilized for capturing two different scenes?

Hey there! I'm currently working on rendering two different scenes with a camera that moves in sync between the two. Here's what I'm trying to accomplish: I need to display two separate point clouds in two distinct scenes, but I want the ca ...

Having trouble with the locality function in Google Places v3 API autocomplete?

After successfully using the code below for about a week, I returned to work on it and found that it was no longer functioning properly. My goal is to only display localities. According to Google's documentation, "locality" is the correct option for a ...

The best method for quickly loading a webpage that is over 20MB in size

My website is a single-page calendar featuring a full year's worth of images. With 344 requests and a total load size of 20MB, the page consists of a simple PHP script without a database. The requests include a CSS file (15KB), 4 JS files (20KB), two ...

How Can You Change the Position of a Threejs Vector3?

I'm attempting to create bones and then manipulate the vertices of each bone, but I am struggling with the correct syntax. Here is an example of what I have tried: var v = new THREE.Vector3(0,0,0); var b = new THREE.Bone(); b.position.x = 5; b.positi ...

Basic example of jQuery in an ASPX file

I can't figure out why this basic example is not working. In my WebApplication, I have a script: function myAlert() { $("#Button1").click(function () { alert("Hello world!"); }); } In my asp page, I have the following code: < ...

Concern with Isotope's masonry feature

I'm at my wit's end! The container div I'm dealing with is 1170px wide. My goal is to fit in 3 divs within this width. The first div is 275px wide, the second is 580px wide, and the third is also 275px wide. Altogether, these divs should ad ...

Show Pop in relation to modified Text

When the user clicks on the text, a pop-up is displayed after the last word in the text.... https://i.stack.imgur.com/VWQCa.png The logic being used is : left = layer.width + layer.x Code : document.getElementById(lightId).style.left = layer.x + docume ...

Electronic circuit embedded within a material-textured text field offering multiline functionality

While experimenting with TagsInput, I came across this helpful snippet on codesandbox that you can check out here. The challenge I encountered is when there are numerous chips, they extend beyond the boundaries of the text field. My goal is to implement ...

Is there a way to stop a music track from playing?

function playMusic(){ var music = new Audio('musicfile.mp3'); if (music.paused) { music.play(); } else { music.pause(); } } <input type="button" value="sound" onclick="playMusic()" ...

Effortlessly saving money with just one click

I have a search text box where the search result is displayed in a graph and then saved in a database. However, I am facing an issue where the data is being saved multiple times - first time saves properly, second time saves twice, third time three times, ...

Organize nested level components in react native into a more structured order

Currently, I am working with some JSON data that has the following structure: const data = { "stores": [ { "name": "s1", "id": "6fbyYnnqUwAEqMmci0cowU", "customers": [ { "id": "4IhkvkCG9WWOykOG0SESWy", ...

I'm experiencing difficulties with JS on my website. Details are provided below – any suggestions on how to resolve this issue

Can someone help me with a web project issue I'm facing? Everything was going smoothly until I tried to add some JS for dynamic functionality. However, when I attempt to access my elements by tag name, ID, or class, they always return null or undefine ...