CLIENT SIDE: function downFile(){ var formData = new FormData(); formData.set('email','$email'); formData.set('gf_line','$line'); formData.set('code','$code'); var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4){ if (this.status == 200) { if (xhttp.responseType == 'text' || xhttp.responseType == '') { alert('Sorry, but there appears to be an error\\nThis could be:\\n\\n- The email address entered\\ndoes not match the email in database\\n\\n- The code you entered is incorrect\\n\\nPlease check your details, and try again'); window.history.back(); return false; } else if (xhttp.responseType == 'blob'){ // Create a new Blob object using the response data of the onload object var blob = new Blob([this.response], {type: 'application/zip'}); //Create a link element, hide it, direct it towards the blob, and then 'click' it programatically let a = document.createElement("a"); a.style = "display: none"; document.body.appendChild(a); //Create a DOMString representing the blob and point the link element towards it let url = window.URL.createObjectURL(blob); a.href = url; a.download = 'Branded Files.zip'; //programatically click the link to trigger the download a.click(); //release the reference to the file by revoking the Object URL window.URL.revokeObjectURL(url); } } } xhttp.open("POST", "download.pl", true); xhttp.send(formData); } SERVER SIDE: ... .. . if ($inEmail ne $email){ print "content-type: text/html\n\n"; print "500"; # Returned as a "TEXT" response exit; } else{ open FILE, "<", "../data/$user/$dir/$code/$fileCode.zip"; binmode FILE; while(){ $file.=$_; } close FILE; #print "content-type: text/html\n\n"; #print "content-type: application/zip\n"; #print "content-disposition: attachment; filename='Branded Files'\n\n"; print $file; # Returned as a "BLOB" response