skip to Main Content

I am trying to use ajax request to do a download for my file. This is my code:

const downloadFile = (element) => { 
    $.ajax({
        url: element.id,
        type: 'GET',  
        success: (result) => {
            window.location=element.id;
        },    
        error: (request,msg,error) => {
            alert(request.responseText);
        }
    })
} 

And HTML element: 
'<td>' + `<a id=hiddenAPIRoute href="#" onclick="downloadFile(this)">Download</a>` + '</td>' +

I am able to download but it does a double download. I like using ajax so I can have better error handling. I am aware of the download attribute of html 5 but I want to include an alert for users to view if the file is not accessible.

2

Answers


  1. You could use fetch and URL.createObjectURL for your workflow. And move your api url to data-href, using id is weird, it’s for another purpose:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <link rel="icon" href="/favicon.ico">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Vite App</title>
    </head>
    
    <body>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <a data-href="https://upload.wikimedia.org/wikipedia/commons/b/b6/Image_created_with_a_mobile_phone.png" href="#"
            onclick="downloadFile(event)">Download</a>
        <script>
    
            const downloadFile = async e => {
                e.preventDefault();
                try {
                    const response = await fetch(e.target.dataset.href);
                    if (response.status !== 200) {
                        throw new Error(await response.text());
                    }
                    const blob = await response.blob();
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = e.target.dataset.href;
                    document.body.appendChild(a);
                    a.click();
                    Promise.resolve().then(() => a.remove());
                } catch (e) {
                    alert(e.message);
                }
            }
    
    
    
        </script>
    </body>
    
    </html>
    
    Login or Signup to reply.
  2. In error handling you can do like this and show the error response however you like:-

        error: function(xhr, status, error1) {
             var err = JSON.parse(xhr.responseText);
             console.log(err)
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search