Javascript not functioning properly on my whole system - javascript

SOLVED: So the problem was that the program broke at when I declared userInput but that was already declared in the js file that I initialized right before this app.js file. Once I changed the name it seems to be better now, thanks all! :D
So i've started a JS tutorial and all the code is doing weird things and not executing in the proper order no matter how many times I close and reopen the program.
I am working on a calculator program from the tutorial so i've copied the code how it appears.
Here is the file structure:
Here is my index.html (notice the script tags at the end of the body)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Basics</title>
<link
href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="assets/styles/app.css" />
</head>
<body>
<header>
<h1>The Unconventional Calculators</h1>
</header>
<section id="calculator">
<input type="number" id="input-number" />
<div id="calc-actions">
<button type="button" id="btn-add">+</button>
<button type="button" id="btn-subtract">-</button>
<button type="button" id="btn-multiply">*</button>
<button type="button" id="btn-divide">/</button>
</div>
</section>
<section id="results">
<h2 id="current-calculation">0</h2>
<h2>Result: <span id="current-result">0</span></h2>
</section>
<script src="assets/scripts/vendor.js"></script>
<script src="assets/scripts/app.js"></script>
</body>
</html>
I put the script tags at the end of the body so the site content is generated first but it still runs the script first sometimes, and only when I refresh enough times does it stop. Weird...
app.js
let currentResult = 10;
currentResult = currentResult + 10 * 3;
let calculationDescription = `${currentResult} (0 + 10)`
outputResult(currentResult, calculationDescription)
alert("hello")
And then when I press Ok on the alert
Only then does the calculation get done. Which is strange because the calculation is written to be executed BEFORE the alert (The calculation did appear a few times while the alert was active, but only 15 seconds later, it doesn't even do that anymore)
When I add..
const userInput = 123;
let result;
After the alert in app.js, the alert stops running entirely!
This makes no sense to me. I wanted to have some js code after the alert so I can put in another alert but this file is making it seem like the alert MUST be the last thing in a js file OR there can only be approx 5 lines in a js file.
Also, the css in the project wasn't working until I moved the entire project from my downloads folder to my desktop (and removed the 5 parent folder hierarchy over it) and there the css did work...
Any idea what can be causing this mess, or is my computer just cursed?
Assumptions:
I've saved the code so it is fully updated
I am using VScode
Running from my OneDrive folder on Windows 10

You essentially asked three questions here:
Why do I see result of my calculation only after closing the alert?
Why does adding const userInput = 123; let result; after the alert prevent the alert from showing up at all?
Why is my CSS not working in some circumstances?
Let me answer all:
Answer to Question 1: Order of execution
The code does execute in order. You can see that if you use the devtools debugger to step through it line by line. What's tripping you up is when the browser redraws page content, as this happens at the end of a tick, when there is no more code to be run in that tick. Rerendering the page instantly whenever something on it gets changed would be very slow (and could induce flicker, depending on what it is that you are updating).
So what happens is this:
Your calculation result is set as content of your element. (But you don't see it yet since the page hasn't been redrawn yet.)
Your alert shows up.
You close the alert.
The call to the alert function returns and the code continues.
No more code is there to run (at least synchronously), and the page is redrawn. (Now you see the changed content.)
In the rare cases where the calculation did show up 15 seconds later, it was probably that something else, something external (such as maybe resizing the window) triggered a redraw despite the alert still being open.
alert isn't the best way to get output anyway, for several reasons: it also obscures a lot of information about more complex data types because it coerces everything to a string, and you cannot easily trace the source of the alert or log the exact time it was shown - all of which are things that console.log would do better.
Answer to Question 2: Why adding code can break everything
Most likely you were introducing a syntax error at that point. For example you may have already declared userInput or result previously, and adding that code made the whole file invalid with a SyntaxError: Identifier 'result' has already been declared or the like, so it wouldn't execute at all.
That's because when a script file (or a <script> tag content) is loaded, it's first parsed (at which point you can encounter "compile-time errors" such as a SyntaxError) and only then it's executed (and then you can encounter "runtime errors" such as a ReferenceError). If you add a single bad character at the very end of your file that's causing a SyntaxError during parsing, the whole file will no longer run.
You would see this error and where it originates from if you'd look into the console tab of your devtools.
In general, I can only recommend learning how to use devtools rather sooner than later: https://www.youtube.com/watch?v=Y3u2groOG-A
Answer to Question 3: Missing styles
It's hard to tell with the information given. Again, a good start would be to check in your devtools for errors in regards to loading the CSS file (in console and network tabs). Also, in case you are using a file:// URI, I'd recommend switching to a local HTTP server instead. Many things behave differently with file:// URIs compared to http:///https://.

Related

how to understand javascript memory leak in this circumstance

I am trying to understand memory leak and I have read blogs as following:
How to handle 4 common memory leaks
Avoiding Memory Leaks in JavaScript
Unfortunately, I still feel confused on this issue.
So, I try to make a test like this:
Firstly, I create a pure HTML containing a huge table within a div#box:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="box">
<table>
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
... hiden 2400 lines of same content row intended for simplicity ...
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
</table>
</div>
</body>
</html>
Then open the devTool and use Console and Memory to make actions and memory recoding:
// 1. Initial "heap snapshot" get 1.9MB
// 2. Running following code on "Console" and "heap snapshot" get 2.2MB
var box = document.getElementById("box");
var tab = document.querySelector("table");
box.removeChild(tab);
tab = null;
// 3. Running following code on "Console" and "heap snapshot" get 2.2MB
box.parentElement.removeChild(box);
box = null;
My confusing is why I almost empty this html DOM tree but the memory consumption is increased.
Any explanation about on JavaScript memory leak will be appreciated! Thanks in advance!

Reference Errors thrown in included file... unless calling file includes slow code

A funny thing happened to me while I was cleaning up some old JavaScript code this week. When I took out some slow code, the page started throwing Reference Errors on code in a file that was included via an Ajax call.
Below is (greatly simplified) example of the issue. The first file will work without error when requested directly. But when called via Ajax, the document-ready event has already occurred, so the code within executes immediately. Chrome throws an error such as: "VM1414:2 Uncaught ReferenceError: they_log is not defined"
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.js"></script>
<script>
$(document).ready(function() {
they_log("Be alerted");
});
</script>
<!-- Two separate script tags prevent hoisting -->
<script>
function they_log($string) {
console.log($string);
}
</script>
</body>
</html>
However, if the comment "alert" line below is uncommented, the Reference Errors are not thrown in Chrome or Firefox (although they still occur in Safari - unless you let the modal dialog hang open for several seconds).
<!doctype html>
<html lang="en">
<head>
<title>Prototype of reference error issue</title>
</head>
<body>
<div id="place" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.js"></script>
<script>
$.get( "http://localhost/path/to/first/file.html", function( data ) {
$("#place").html(data);
});
//alert("I get rid of the reference error");
</script>
</body>
</html>
My question is, how does the alert message (or similar slow code in the including file) prevent the reference errors from occuring?
I'm particularly interested if whatever is happening to let the code execute without error can be counted on to work consistently (in Chrome and Firefox, at least) or if there is something like a race condition going on where it may fail intermittently.
What I observe is your alert run before document ready, and it prevents document ready until the alert dialog is closed. Fiddle: https://jsfiddle.net/24pg3yzk/
While the alert dialog is displayed, the Ajax request and its done handler $("#place").html(data); may have finished. So yes, it's race condition.
Is it standard or consistent behavior? I don't know. I think it makes sense since alert "Dialog boxes are modal windows - they prevent the user from accessing the rest of the program's interface until the dialog box is closed" (source), but nothing to affirm it from the jQuery doc.

How is this XSS attack working?

SPOILER ALERT: This question contains an answer to one of the problems from the Google's XSS Challenge! Please stop reading further if you're not interested in knowing the answer right now.
I'm able to get pass the level 4 of the challenge, however, I still don't know how exactly the exploit is working. The following is the code from Google's XSS challenge - Level 4:
<!doctype html>
<html>
<head>
<!-- Internal game scripts/styles, mostly boring stuff -->
<script src="/static/game-frame.js"></script>
<link rel="stylesheet" href="/static/game-frame-styles.css" />
<script>
function startTimer(seconds) {
seconds = parseInt(seconds) || 3;
setTimeout(function() {
window.confirm("Time is up!");
window.history.back();
}, seconds * 1000);
}
</script>
</head>
<body id="level4">
<img src="/static/logos/level4.png" />
<br>
<img src="/static/loading.gif" onload="startTimer('{{ timer }}');" />
<br>
<div id="message">Your timer will execute in {{ timer }} seconds.</div>
</body>
</html>
Basically, they are using Django framework (which uses a bunch of security measure against XSS). The variable timer carries the input from the user. The goal of this activity is to alert a message by sending a payload which can bypass Django's XSS security.
I'm able to alert a message using one of the following payloads:
');alert('xss
OR
3') || alert('1
I'm able to clear the level using the above payloads but I'm still not sure where exactly the alert() method is being called? In the onload handler OR within the startTimer() method?
I'm confused because if I check the source HTML of the page after submitting the payload, Django is encoding the payload:
<html>
<head>
<!-- Internal game scripts/styles, mostly boring stuff -->
<script src="/static/game-frame.js"></script>
<link rel="stylesheet" href="/static/game-frame-styles.css" />
<script>
function startTimer(seconds) {
seconds = parseInt(seconds) || 3;
setTimeout(function() {
window.confirm("Time is up!");
window.history.back();
}, seconds * 1000);
}
</script>
</head>
<body id="level4">
<img src="/static/logos/level4.png" />
<br>
<img src="/static/loading.gif" onload="startTimer('');alert('xss');" />
<br>
<div id="message">Your timer will execute in ');alert('xss seconds.</div>
</body>
</html>
What seems to be confusing you is the mix of two different languages: HTML and JavaScript. ' is HTML. It's translated to the ' character when displayed and when interpreted as JavaScript. That means, from the JavaScript interpreter's point of view, there's no difference between ' and '. The code onload="startTimer('');alert('xss');" is effectively the same as onload="startTimer('');alert('xss');" even though at the first glance it looks like something that shouldn't work.
I see why the XSS worked! One of the section in the OWASP XSS cheat sheet says:
HTML entity encoding is okay for untrusted data that you put in the
body of the HTML document, such as inside a tag. It even sort of
works for untrusted data that goes into attributes, particularly if
you're religious about using quotes around your attributes. But HTML
entity encoding doesn't work if you're putting untrusted data inside a
tag anywhere, or an event handler attribute like onmouseover,
or inside CSS, or in a URL. So even if you use an HTML entity encoding
method everywhere, you are still most likely vulnerable to XSS. You
MUST use the escape syntax for the part of the HTML document you're
putting untrusted data into. That's what the rules below are all
about.
In this case, the user input is being fed into an event handler, which will treat it as a JS instead of HTML. And, the input is being escaped in HTML context (not in JS context). Therefore, JS will treat startTimer('3') || alert('1'); as startTimer('') || alert('1'); and will simply run this script.
PS: JS escaping might have prevented the attack.

IE does not read <script> tag, but after refresh works fine

I have a weird bug that is present only in IE (7/8/9/9CV).
FF and Chrome do not have this issue.
I have a pretty big, complex page. In the bottom of the page I have two pieces of JavaScript code right one after another. The first one has no problems, but the second one for some reason is being displayed as a text when I load the page first time. If I just refresh the page without doing anything else - everything works and looks just fine.
Two pieces of JS being generated on a server from two different pagelets so I cannot put them together into one script tag. The first piece of JavaScript code is nothing more but a call to the same function couple of times with different parameters, and the second script is just a declaration of a JSON like object that is being consumed by another function that is defined earlier on the page.
So the page code looks something like this:
<!DOCTYPE html>
<html>
<head>
...
<title>...</title>
</head>
<body>
...
<script type="text/javascript">
//Some javascript that executes perfectly fine every time and is nothing more but just couple of calls to some function
someFunction("param1");
someFunction("param2");
someFunction("param3");
</script>
<script type="text/javascript">
var myObject = {"success":[{"header":"Form successfully submitted","messages":["Some message 1"]}]};
</script>
</body>
</html>
So when a form submitting happens I take this object and use it to display a message on the page. But instead, when user submits the form and it opens the page for the first time, I see this in the bottom of the page:
var myObject= {"success":[{"header":"Form successfully submitted","messages":["Some message 1"]}]};
But when I refresh the page - I do not see that code, but instead I see the message being displayed with values from this object.
When I open the "developer tools" and navigate to the HTML tab, I see that my tag for the second JS piece is shown as commented out!
<!-- sctipt ... -->
But if I refresh the page - it works fine, and in HTML tab of the developer tools it actually shown as a script node that I can expand and see the Javascript code.
Does anyone know what is going on here?!?! This issue has been bugging me for couple of days now!
You should replace
<script type="text/javascipt">
with
<script type="text/javascript">
EDIT :
HTML isn't XHTML. Don't wrap your scripts inside CDATA. Your script elements should be simply like this :
<script type="text/javascript">
var t0_date = new Date();
...
</script>
Change both these:
<script type="text/javascipt">
to:
<script type="text/javascript">
Well, I found an answer to this problem. Well, more of a work around I guess, as this is not something I expected but it works.
Basically, if you put anything between the two script elements - IE wokrs fine!
So what I did was - I put br tag in between and it now works fine. I have no idea why. Perhaps some weird bug in IE rendering engine.
The end result looks like this:
<script type="text/javascript">
//Some javascript that executes perfectly fine every time and is nothing more but just couple of calls to some function
someFunction("param1");
someFunction("param2");
someFunction("param3");
</script>
<br>
<script type="text/javascript">
var myObject = {"success":[{"header":"Form successfully submitted","messages":["Some message 1"]}]};
</script>

Eval already loaded script tag

I have the following code
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<script type='text/javascript' src="js.js" id="scripter"></script>
</head>
<body>
<button>AGAIN</button>
</body>
</html>
The included js has as set of statements whichg gets executed as soon as the page load.
* NOTE : it does not contain any function and dont want to contain any function.
On click of the button AGAIN i want to eval the entire script once again. Any possible ways this can be done ??
Trying to get the script contents of the script included so that I can eval it.
Any possible ways this can be achieved ??
OR
Some other method to achieve the same ??
Thanks.
For people downvoting this : I know those are what functions are for, hence specified note specifically. Maybe I should have asked the latter part of the question directly wtihout giving much details. Is it possible for me to access the scripts content that gets included in a page ??
It can be achieved by setting <script>'s src attribute to the same with a random get variable like
scriptTag.src = scriptTag.src + "?r=" + Math.random();
which will cause the browser to load the entire file again and that's usually not a good idea, but that's how it could be done
I dont know how big that JS file of yours is but - if its possible - you can write that file as
$someVariable = ' Whole Javascript code in quotes';
And whenever you want to run the code again just call eval($someVariable).
Now you might have a question for me. How is it gunna run at the very first time.
just add following line at the end of your JS file.
eval($someVariable);

Categories

Resources