Cross-browser alternative of Date.now() and innerHTML security? - javascript

I have PHP form validation rules working but I also don't want valid but nonsense real human-being spams. Currently, the JavaScript code below gets the timestamp of the page loaded time and the timestamp of the form submission. If the difference is below 18 seconds it asks 'are you superman?' in an alert box and doesn't allow the user to submit until time arrives.
Q1 ) Date.now() is supported by ie9+. Which alternative function achieves the same work in ie7+ ? (reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Browser_compatibility)
Q2 ) Does this function itself has security gap? I ask because I suspect of document.getElementById('PageLoadTime').innerHTML = pageloaded code if variable pageloaded could be edited from outside!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>trial</title>
</head>
<body>
<div>user page loading timestamp: <span id="PageLoadTime"></span></div>
<div>form submission timestamp: <span id="submitTime"></span></div>
<div>time difference: <span id="difference"></span></div>
<script>
var pageloaded = Date.now();
document.getElementById('PageLoadTime').innerHTML = pageloaded;
function GetSubmitTime(pageloaded) {
document.getElementById('submitTime').innerHTML = Date.now();
document.getElementById('difference').innerHTML = Math.floor((Date.now() - pageloaded)/1000);
if ( Math.floor((Date.now() - pageloaded)/1000) < 18 )
{
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false; // for IE as dont support preventDefault;
}
alert("are you superman?");
}
}
</script>
<form method="post" action="my home page" onsubmit="GetSubmitTime(pageloaded)">
<input type="text" id="e1" name="n1">
<input type="submit" value="send" >
</form>
</body>
</html>

Date.now() returns what new Date().getTime() returns, and the latter has been supported essentially forever.
Setting the innerHTML of an element to a system timestamp is not a security risk.
Nothing in the client is safe from user tampering. Anybody using your form can force the form to be submitted without any regard to your time check.

Answer to your first question. Put the following at the top of your JavaScript and you can use Date.now() even on IE < IE9.
Date.now = Date.now || function() { return +new Date; };
console.log(Date.now()); // 1406206659562
Furthermore, your code in general is fine, though the security on the client side is always relative.

Related

How to stop page from auto refreshing with JavaScript?

I am quite new to web dev and currently, I work on a JS course. I have a problem with the automatic page refreshing that happens in Chrome and Safari also.
I have read that this refreshing can be caused by input submission in HTML but this problem occurs even when I do not use any type of button. In the code below, I tried to make a counter of the best score of all games when I guess the numbers, but I cannot record this score because my browser randomly refreshes my localhost and therefore all data is lost. As I said this problem occurs even when I do not use any type of submitting in my code (page randomly refreshes itself).
I have tried to disable adblocker in my browsers, but this did not help. Also, I tried to use window.stop() at the start and end of the code, but this did not seem desirable because safari always showed that it is still loading the page. Also, I have read that this can be caused by some sort of RAM optimization in the browser and therefore I tried to execute the code with only one tab open but this did not help either. I use Live Server extension with VS Code and therefore I do not run live server with node.js through terminal.
Because this problem occurs in multiple browsers I figured that it can be solved by some additional code in JS for example. Do you have any idea how could I solve this problem? I have run out of ideas at this point.
My Code:
"use strict";
let secretNumber = Math.trunc(Math.random() * 20) + 1;
let score = 20;
let highScore = 0;
document.querySelector(".check").addEventListener("click", function() {
const guess = Number(document.querySelector(".guess").value);
if (!guess) {
// When there is no input
document.querySelector(".message").textContent = "No Number";
} else if (secretNumber === guess) {
// When correct guess
document.querySelector(".number").textContent = secretNumber;
document.querySelector(".message").textContent = "Correct guess! 🎉";
document.querySelector("body").style.backgroundColor = "#228B22";
if (score > highScore) {
highScore = score;
document.querySelector(".highscore").textContent = highScore;
}
} else if (secretNumber < guess) {
// When guess is too high
if (score > 1) {
score--;
document.querySelector(".score").textContent = score;
document.querySelector(".message").textContent = "Too High";
} else {
document.querySelector(".score").textContent = 0;
document.querySelector(".message").textContent = "You lost the game.";
}
} else {
// When guess is too low
if (score > 1) {
score--;
document.querySelector(".score").textContent = score;
document.querySelector(".message").textContent = "Too Low";
} else {
document.querySelector(".score").textContent = 0;
document.querySelector(".message").textContent = "You lost the game.";
}
}
// Reseting Game With Button
document.querySelector(".again").addEventListener("click", function() {
score = 20;
document.querySelector(".score").textContent = score;
secretNumber = Math.trunc(Math.random() * 20) + 1;
document.querySelector(".message").textContent = "Start Guessing";
document.querySelector(".number").textContent = "?";
document.querySelector("body").style.backgroundColor = "#222222";
document.querySelector(".guess").value = "";
});
});
<!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" />
<link rel="stylesheet" href="style.css" />
<title>Guess My Number!</title>
</head>
<body>
<header>
<h1>Guess My Number!</h1>
<p class="between">(Between 1 and 20)</p>
<button class="btn again">Again!</button>
<div class="number">?</div>
</header>
<main>
<section class="left">
<input type="number" class="guess" />
<button class="btn check">Check!</button>
</section>
<section class="right">
<p class="message">Start guessing...</p>
<p class="label-score">💯 Score: <span class="score">20</span></p>
<p class="label-highscore">
🥇 Highscore: <span class="highscore">0</span>
</p>
</section>
</main>
<script src="script.js"></script>
</body>
</html>
Currently, I use this Chrome version "Version 92.0.4515.159 (Official Build) (arm64)" and this Safari version "Version 14.1.2 (16611.3.10.1.3)" with MacBook Air(2020) with M1 chip and 16 GB of RAM.
I use Live Server extension with VS Code…
This extension is designed to refresh your browser every time your file is changed (in some cases using the file buffer in VSCode). Disable the extension if you don't want this behavior.
Apparently, there is a problem with refreshing browser windows with localhost when loading code from external SSD. I disabled the Live Server extension in VS Code and installed node.js and run the live server from there but this did not help either. When I moved my files from the external SSD into the machine everything worked correctly.

"document.forms.value" - Undefined in Microsoft Edge

I wrote a very quick javascript function to validate a very small form on an internal form used in our office. However, someoner today told me that it doesnt work in Edge, the code does not ever enable the submit button.
I console.log out the var values every time the function runs, and in edge, the vars are forever undefined. It seems like Edge does not respect "document.forms["abc"]["xyz"].value", but I cannot find any documentation or notes to support that.
I should clarify, I am not a javascript pro, I uyse it very sparingly, and in simple ways to get smal tasks done like this, so please dont judge my code too hard, haha.
Console Log:
q1=undefined
q2=undefined
q3=undefined
q4=undefined
My code is below, its pretty simple, nothing fancy..
function fieldcheck(){
var q1=document.forms["datacollect1"]["q1overall"].value;
var q2=document.forms["datacollect1"]["q2understand"].value;
var q3=document.forms["datacollect1"]["q3time"].value;
var q4=document.forms["datacollect1"]["q4recommend"].value;
console.log("q1="+q1+"\n"+"q2="+q2+"\n"+"q3="+q3+"\n"+"q4="+q4);
document.getElementById("datacollectsubmit1").disabled = true;
if (q1 && q2 && q3 && q4){
console.log("q1234 set");
document.getElementById("datacollectsubmit1").disabled = false;
}
}
I call the above on every click with:
document.onclick = function(){
fieldcheck();
}
Anyone have any clue as to why Edge is playing games? Or what I can substiture for document.forms.value that will work across other browsers and Edge too? Thanks.
Your above code is working in MS Edge. Possible that some other code caused this issue. I suggest you to take the code below and run it in MS Edge.
Code:
<!doctype html>
<head>
<script>
function fieldcheck(){
var q1=document.forms["datacollect1"]["q1overall"].value;
var q2=document.forms["datacollect1"]["q2understand"].value;
var q3=document.forms["datacollect1"]["q3time"].value;
var q4=document.forms["datacollect1"]["q4recommend"].value;
console.log("q1="+q1+"\n"+"q2="+q2+"\n"+"q3="+q3+"\n"+"q4="+q4);
document.getElementById("datacollectsubmit1").disabled = true;
if (q1 && q2 && q3 && q4){
console.log("q1234 set");
document.getElementById("datacollectsubmit1").disabled = false;
}
}
document.onclick = function(){
fieldcheck();
}
</script>
</head>
<body>
<form name="datacollect1" onsubmit="return fieldcheck()" method="post">
Name: <input type="text" name="q1overall"><br>
Name1: <input type="text" name="q2understand"><br>
Name2: <input type="text" name="q3time"><br>
Name3: <input type="text" name="q4recommend"><br><br>
<input type="submit" id="datacollectsubmit1" value="Submit">
</form>
</body>
</html>
Output in MS Edge browser:

Get client hostname [duplicate]

How can I read the client's machine/computer name from the browser?
Is it possible using JavaScript and/or ASP.NET?
You can do it with IE 'sometimes' as I have done this for an internal application on an intranet which is IE only. Try the following:
function GetComputerName() {
try {
var network = new ActiveXObject('WScript.Network');
// Show a pop up if it works
alert(network.computerName);
}
catch (e) { }
}
It may or may not require some specific security setting setup in IE as well to allow the browser to access the ActiveX object.
Here is a link to some more info on WScript: More Information
Browser, Operating System, Screen Colors, Screen Resolution, Flash version, and Java Support should all be detectable from JavaScript (and maybe a few more). However, computer name is not possible.
EDIT: Not possible across all browser at least.
Well you could get the ip address using asp.net, then do a reverse DNS lookup on the ip to get the hostname.
From the ASP.NET Developer's cookbook ... Performing a Reverse-DNS Lookup.
It is not possible to get the users computer name with Javascript. You can get all details about the browser and network. But not more than that.
Like some one answered in one of the previous question today.
I already did a favor of visiting your website, May be I will return or refer other friends.. I also told you where I am and what OS, Browser and screen resolution I use Why do you want to know the color of my underwear? ;-)
You cannot do it using asp.net as well.
Try getting the client computer name in Mozilla Firefox by using the code given below.
netscape.security.PrivilegeManager.enablePrivilege( 'UniversalXPConnect' );
var dnsComp = Components.classes["#mozilla.org/network/dns-service;1"];
var dnsSvc = dnsComp.getService(Components.interfaces.nsIDNSService);
var compName = dnsSvc.myHostName;
Also, the same piece of code can be put as an extension, and it can called from your web page.
Please find the sample code below.
Extension code:
var myExtension = {
myListener: function(evt) {
//netscape.security.PrivilegeManager.enablePrivilege( 'UniversalXPConnect' );
var dnsComp = Components.classes["#mozilla.org/network/dns-service;1"];
var dnsSvc = dnsComp.getService(Components.interfaces.nsIDNSService);
var compName = dnsSvc.myHostName;
content.document.getElementById("compname").value = compName ;
}
}
document.addEventListener("MyExtensionEvent", function(e) { myExtension.myListener(e); }, false, true); //this event will raised from the webpage
Webpage Code:
<html>
<body onload = "load()">
<script>
function showcomp()
{
alert("your computer name is " + document.getElementById("compname").value);
}
function load()
{
//var element = document.createElement("MyExtensionDataElement");
//element.setAttribute("attribute1", "foobar");
//element.setAttribute("attribute2", "hello world");
//document.documentElement.appendChild(element);
var evt = document.createEvent("Events");
evt.initEvent("MyExtensionEvent", true, false);
//element.dispatchEvent(evt);
document.getElementById("compname").dispatchEvent(evt); //this raises the MyExtensionEvent event , which assigns the client computer name to the hidden variable.
}
</script>
<form name="login_form" id="login_form">
<input type = "text" name = "txtname" id = "txtnamee" tabindex = "1"/>
<input type="hidden" name="compname" value="" id = "compname" />
<input type = "button" onclick = "showcomp()" tabindex = "2"/>
</form>
</body>
</html>
There is no way to do so, as JavaScript does not have an access to computer name, file system and other local info. Security is the main purpose.
No this data is not exposed. The only data that is available is what is exposed through the HTTP request which might include their OS and other such information. But certainly not machine name.
<html>
<body onload = "load()">
<script>
function load(){
try {
var ax = new ActiveXObject("WScript.Network");
alert('User: ' + ax.UserName );
alert('Computer: ' + ax.ComputerName);
}
catch (e) {
document.write('Permission to access computer name is denied' + '<br />');
}
}
</script>
</body>
</html>
There is some infos to parse into the webRTC header.
var p = new window.RTCPeerConnection();
p.createDataChannel(null);
p.createOffer().then((d) => p.setLocalDescription(d))
p.onicecandidate = (e) => console.log(p.localDescription)
An updated version from Kelsey :
$(function GetInfo() {
var network = new ActiveXObject('WScript.Network');
alert('User ID : ' + network.UserName + '\nComputer Name : ' + network.ComputerName + '\nDomain Name : ' + network.UserDomain);
document.getElementById('<%= currUserID.ClientID %>').value = network.UserName;
document.getElementById('<%= currMachineName.ClientID %>').value = network.ComputerName;
document.getElementById('<%= currMachineDOmain.ClientID %>').value = network.UserDomain;
});
To store the value, add these control :
<asp:HiddenField ID="currUserID" runat="server" /> <asp:HiddenField ID="currMachineName" runat="server" /> <asp:HiddenField ID="currMachineDOmain" runat="server" />
Where you also can calling it from behind like this :
Page.ClientScript.RegisterStartupScript(this.GetType(), "MachineInfo", "GetInfo();", true);
Erm is there any reason why you can't just use the HttpRequest? This would be on the server side but you could pass it to the javascript if you needed to?
Page.Request.UserHostName
HttpRequest.UserHostName
The one problem with this is it would only really work in an Intranet environment otherwise it would just end up picking up the users Router or Proxy address...

post form values to html

I want to POST form values and display them on another html page using Javascript. No server-side technology should be used. I have a function that posts the values but to read the values to another html page, I think I am missing something. Below is the code.
Any help? Thanks in advance.
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
<script type="text/javascript">
function post_to_page(path, params, method) {
method = method || "post"; // Set method to post by default, if not specified.
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
form.setAttribute("target", "formresult");
for (var key in params) {
if (params.hasOwnProperty(key)) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
// creating the 'formresult' window with custom features prior to submitting the form
window.open('target.htm', 'formresult', 'scrollbars=no,menubar=no,height=600,width=800,resizable=yes,toolbar=no,status=no');
form.submit();
}
</script>
</head>
<body>
<form id="form1" action="target.htm" method="post">
<div>
USB No: <input name="usbnum" id="usbnum" type="text"/><br />
USB Code: <input name="usbcode" id="usbcode" type="text"/>
</div>
<button onclick="post_to_page()">Try it</button>
</div>
</form>
</body>
</html>
Here is a simple example of moving data from one Window to another
<!-- HTML -->
<textarea id="foo"></textarea><br/>
<input id="bar" value="click" type="button"/>
and the real code to make it work, which assumes you pass the same origin policy
// JavaScript
var whatever = 'yay I can share information';
// in following functions `wnd` is the reference to target window
function generateWhatever(wnd, whatever) { // create the function actually doing the work
return function () {wnd.document.getElementById('foo').innerHTML = whatever};
} // why am I using a generator? You don't have to, it's a choice
function callWhenReady(wnd, fn) { // make sure you only invoke when things exist
if (wnd.loaded) fn(); // already loaded flag (see penultimate line)
else wnd.addEventListener('load', fn); // else wait for load
}
function makeButtonDoStuff() { // seperated button JS from HTML
document
.getElementById('bar')
.addEventListener('click', function () {
var wnd = window.open(window.location); // open new window, keep reference
callWhenReady(wnd, generateWhatever(wnd, whatever)); // set up function to be called
});
}
window.addEventListener('load', function () {window.loaded = true;}); // set loaded flag (do this on your target, this example uses same page)
window.addEventListener('load', makeButtonDoStuff); // link button's JavaScript to HTML when button exists
You can't get POST values using JavaScript. You can use GET method to pass values.
If you are using html5 you can use localStorage. Otherwise a query string or cookies are your other options.
You said you didn't want the server involved...why are you calling submit?
[Edit]
#Paul S's comment/answer looks very helpful. But you might look at something like the jQuery PostMessage plugin if you need it to be cross browser compatible.
http://benalman.com/projects/jquery-postmessage-plugin/
You don't require a POST request to send data from one page to another. Simply use LocalStorage to do the trick. Just call a Javascript function on form submission. This may help:
HTML:
<form id="form1" action="target.htm" method="post">
<div>
USB No: <input name="usbnum" id="usbnum" type="text"/><br />
USB Code: <input name="usbcode" id="usbcode" type="text"/>
</div>
<button onclick="post_to_page()">Try it</button>
</form>
Javascript:
function post_to_page() {
localStorage.value = "Your content here";
window.location = "nextpage.html";
}
This will save the data locally and go to the next page. In the next page, simply call this function to retrieve the stored data:
function get_stored_data() {
alert(localStorage.value);
}
You can simply assign it to a div, textbox other Javascript variable.

FireFox capture autocomplete input change event

I'm trying to subscribe to change events on an input tag for an ajax auto complete form. These change events are not firing when the user clicks an autocomplete suggestion from FireFox.
I've seen fixes for IE, but not FireFox. You can view this behavior here
Steps to recreate:
type any input in one of the boxes and click submit.
Start typing the value again in the same box.
You should see the autocomplete suggestion box appear below the input box. Notice that clicking the suggestion does not fire the change event (it also doesn't fire the click event)
Currently my only option is to disable autocomplete on this field, but I do not want to do that.
Firefox 4+ fire 'oninput' event when autocomplete is used.
Here's some jQuery to make this more actionable:
$('#password').bind('input', function(){ /* your code */});
I've had the same problem.
Apparently, there is password manager debugging available
https://wiki.mozilla.org/Firefox:Password_Manager_Debugging
So I've found that for me DOMAutoComplete event got triggered and
I've managed to attach it sucessfuly to a field via jQuery's bind like
$('#email').bind('DOMAutoComplete',function() { ...
If it makes you feel better, it is a known bug
Proposed workaround: (Not mine, from here
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Mozilla Firefox Problem</title>
<script type="text/javascript">
function fOnChange()
{
alert('OnChange Fired');
}
var val_textBox;
function fOnFocus()
{
val_textBox = document.getElementById('textBox').value;
}
function fOnBlur()
{
if (val_textBox != document.getElementById('textBox').value) {
fOnChange();
}
}
</script>
</head>
<body>
<form name="frm">
<table>
<tr>
<td><input type="text" id="textBox" name="textBox" onFocus="fOnFocus()" onBlur="fOnBlur()"></td>
</tr>
<tr>
<td><input type="submit" value="Submit"></td>
</tr>
</form>
</body>
</html>
Another Suggested work around. This time using polling, you can work it in exactly
the same way, checking for "changes" to your field. Tweak the poll value (default to
375ms for your own taste).
I've used jQuery and a jquery plugin someone wrote:
https://github.com/cowboy/jquery-dotimeout/
Git Hub Src: https://raw.github.com/cowboy/jquery-dotimeout/master/jquery.ba-dotimeout.js
<html>
<head>
<meta charset="utf-8">
<title>onChange() for Firefox / IE autofil get-around</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="/~dsloan/js/ba-dotimeout.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var val;
var count=0; // used to illustrate the "poll count"
// when focusing on the element and typing
// (vs not focused)
// set a focus function to poll the input
$("#myname").focus(function() {
// start polling
$.doTimeout('checkname', 375, function() {
++count;
// no changes, just exit this poll
if($("#myname").val() == val) {
return true;
// store the value
} else {
val = $("#myname").val();
}
var str;
// do stuff here with your field....
if($(document.activeElement) &&
($(document.activeElement).attr('id') ==
$("#myname").attr('id'))) {
var len = $("#myname").val().length;
if(len == 0) {
str = 'Timer called, length 0...';
} else if(len < 2) {
str = 'Timer called, length < 2...';
} else {
str = 'Timer called, valid!';
}
}
// show some debugging...
$("#foo span").html(str+' (count: '+count+'): '+
$(document.activeElement).attr('id')+
', val: '+$("#myname").val());
return true;
});
});
// set a blur function to remove the poll
$("#myname").blur(function() {
$.doTimeout('checkname');
});
});
</script>
</head>
<body>
<form action="#" method=post>
Name: <input type="text" name="name" value="" id="myname" />
Scooby: <input name="scooby" value="" id="scooby" />
<input type="submit" value="Press Me!" />
</form>
<div id="foo"><span></span></div>
</body>
</html>
A possibly alternative: could you simply use a timer to tell when the value of the text box changes?
You're going to have to blur the input field and reset the focus to it. That's going to require a little trickeration though.

Categories

Resources