This is the script that i am using to fetch a particular cookie lastvisit :
AFTER THE EDIT
// This document writes a cookie
// called from index.php
window.onload = makeLastVisitCookie;
function makeLastVisitCookie() {
var now = new Date();
var last = new Date();
now.setFullYear(2020);
// set the cookie
document.cookie = "lastvisit=" + last.toDateString() + ";path=/;expires=" + now.toGMTString();
var allCookies = document.cookie.split(";");
for( var i=0 ; i < allCookies.length ; i++ ) {
if(allCookies[i].split("=")[0]== "lastvisit") {
document.getElementById("last_visit").innerHTML = "You visited this site on" + allCookies[i].split("=")[1];
} else {
alert("testing..testing..");
}
}
}
From this script the if part never works though there are 5 cookies stored from my website. (including the cookie that i am saving from this script) What is the mistake that i am making while fetching the cookie named lastvisit ?
You're splitting the cookie by ; an comparing those tokens with lastvisit. You need to split such a token by = first. allCookies[i] looks like key=val and will never equal lastvisit. Een if allCookies[i] == "lastvisit" is true, the result will still not be as expected since you're showing the value of allCookies[i + 1] which would be this=the_cookie_after_lastvisit.
if(allCookies[i].split("=") == "lastvisit") { should be:
var pair = allCookies[i].split("=", 2);
if (pair[0].replace(/^ +/, "") == "lastvisit") {
"You visited this site on" + allCookies[i+1]; should be:
"You visited this site on" + pair[1];
The 2 argument of split makes cookies like sum=1+1=2 be read correctly. When splitting cookies by ;, the key may contain a leading space which much be removed before comparing. (/^ +/ is a regular expression where ^ matches the beginning of a string and + one or more spaces.)
Alternatively, compare it directly against a RE for matching the optional spaces as well (* matches zero or more occurences of a space character, $ matches the end of a string):
if (/^ *lastvisit$/.test(pair[0])) {
I've tested several ways to get a cookie including using regular expressions and the below was the most correct one with best performance:
function getCookie(name) {
var cookie = "; " + document.cookie + ";";
var search = "; " + encodeURIComponent(name) + "=";
var value_start = cookie.indexOf(search);
if (value_start == -1) return "";
value_start += search.length;
var value_end = cookie.indexOf(';', value_start);
return decodeURIComponent(cookie.substring(value_start, value_end))
}
You need to remove possible white space around the cookie key before comparing to the string "lastvisit". This is done conveniently using regular expressions. /^\s+/ matches all white space at the beginning, /\s+$/ matches all white space at the end. The matches are replaced by the empty string, i.e. removed:
for( var i = 0 ; i < allCookies.length ; i++ ) {
var c = allCookies[i].split("="); // split only once
var key = c[0].replace(/^\s+/, '').replace (/\s+$/, ''); // remove blanks around key
if (key == "lastvisit") {
document.getElementById("last_visit").innerHTML = "You visited on " + c[1];
}
//...
}
Related
Lets say I have the following string, which I may receive and require my program to act up on:
ACTION -F filter string -L location string -M message string
How can I reliably extract the 'arguments' from this string, all of which are optional to the user?
I spent a lot of time instead writing ACTION, filter, location, message and using .split(", ") to put the args to an array but found this too difficult to work reliably.
var content = req.body.Body.split(", "); // [ Type, Filter, Location, Message]
var msgType = content[0].trim().toUpperCase();
if (msgType === 'INFO') {
// return info based on remainder of parameters
var filterGroup = content[1].trim();
var destination = content[2].trim();
var message = '';
// The message may be split further if it is written
// with a ',' so concat them back together.
if (content.length > 2) { // Optional message exists
// Message may be written in content[3] > content[n]
// depending how many ', ' were written in the message.
for (var i = 3; i < content.length; i++) {
message += content[i] + ", ";
}
}
}
Is the -a argument format even the best way? Much googling returns information on extracting the arguments used to run a nodeJS program, but that isn't applicable here, as the program is already running and the string not used at runtime. I'm at the design stage so have complete control over the format of the user input, but they're sending a SMS with these commands so the simpler the better!
I'm writing in javascript and would appreciate your thoughts
You can use a regex to match the -X pattern and then use a loop to extract the strings between each pattern match.
The regex here is /(?<=\s)\-[A-Za-z](?=\s)/g, which looks for a dash followed by a letter with a white space character on either side.
const input = "ACTION -F filter string -L location string -M message string";
let regex = /(?<=\s)\-[A-Za-z](?=\s)/g;
let args = [];
while(match = regex.exec(input))
{
args.push(match);
}
let solved = [];
for(let i = 0; i < args.length; i++)
{
let cmd = args[i][0];
let idx = args[i].index;
let val;
if(i + 1 == args.length)
val = input.substr(idx + cmd.length + 1);
else
val = input.substring(idx + cmd.length + 1, args[i + 1].index - 1);
solved.push({
cmd: cmd,
val: val
});
}
console.log(solved);
My goal is to edit the string (which has an email) to mask the first part, like say the email is johndoe#abc.com then I should output j*****e#abc.com.
var maskPII = function(S) {
var ans = "";
if(S.includes("#")){
S = S.toLowerCase();
var parts = S.split("#");
var first = parts[0];
for(var i=0;i<parts[0].length;i++){
if(i!=0 && i!=parts[0].length - 1)
first[i] = '*';
}
ans = first +"#" +parts[1];
}else{
}
return ans;
};
However in my loop I can't change the characters to asterisks.
After execution I see value of first still same as parts[0] and has no asterisks, can some one explain why? Also, what would I need to do to modify the variable inside loop?
To answer your question... javascript allows you access values of a string using [] indexing.. but that is read only access... you cannot insert/replace values using that operator.
Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
When using bracket notation for character access,
attempting to delete or assign a value to these properties will not succeed.
The properties involved are neither writable nor configurable.
(See Object.defineProperty() for more information.)
You need to extract the values you want to keep from the existing string and build up a new string as noted in other answers...
Well, this's what you're looking for, and this will be the output j*****e#abc.com.
var ans = "";
var S = "johndoe#abc.com"; //example
S = S.toLowerCase();
var parts = S.split("#");
var first = "";
for(var i = 0; i < parts[0].length; i++){
if(i != 0 && i != parts[0].length - 1){
first += '*';
}else{
first += parts[0][i];
}
}
ans = first +"#"+ parts[1];
console.log(ans);
Here is the code with your approach:
var maskPII = function(S) {
var ans = "";
if(S.includes("#")){
S = S.toLowerCase();
var parts = S.split("#");
var first = parts[0][0];
for(var i=0;i<parts[0].length;i++){
if(i!=0 && i!=parts[0].length - 1)
first += '*';
}
ans = first + parts[0][parts[0].length - 1] +"#" +parts[1];
}else{
}
return ans;
};
But if i were you i would use:
var mail = "johndoe#abc.com";
mail = mail.replace(/(?<=.)(.+?)(?=.#)/gi, '*'.repeat(mail.split('#')[0].length - 2));
console.log(mail);
You can use the bracket notation on a string (like an array) to get the character at a specific index, but you can't use this to change characters. So first[i] = '*' in your code wont do anything.
Strings in JavaScript are immutable. This means that if you want to change a string, a new string instance will be created. This also means that when you change a string in a for-loop, it can impact performance. (Although in this case the difference wont be noticeable.
)
I would use this code:
function maskPII(str) {
const indexOfAt = str.indexOf('#');
if (indexOfAt <= 2) {
return str;
}
return str[0] + '*'.repeat(indexOfAt - 2) + str.substring(indexOfAt - 1);
}
const email = 'johndoe#abc.com';
console.log(email);
console.log(maskPII(email));
It will look for the index of the # sign. If the index is less or equal than 2, (when not found the index will be -1) it will return the original string.
Otherwise it will get the first character, calculate the amount of asterisks needed (index of the # sign -2) and repeat those and then add the rest of the original string.
I have column in my database named rate but the datatype is string and has values like '2000+'. When I try to show this value using jQuery, why is it only showing 2000 without the '+' sign?
for (var j = 0; j < dtt2.length; j++) { if (dt0[i].CategoryID === dtt2[j].CategoryID) { var rate = dtt2[j].Rate; alert(rate.tostring()); $("#" + tbl).append('<tr><td>' + dtt2[j].ServiceName + '</td><td width="20%">₹ ' + rate.tostring() + '</td></tr>'); } }
this code is working when running on local host but when i am hosting on production the error comes string without + sign
Below is the code behind code-
foreach (DataRow dr in dt2.Rows)
{
ServiceRateList sd = new ServiceRateList();
sd.ServiceDetailID = Convert.ToInt32(dr["ServiceDetailID"]);
sd.ServiceName = dr["ServiceName"].ToString();
sd.CategoryID = Convert.ToInt32(dr["CategoryID"].ToString());
sd.CategoryName = dr["CategoryName"].ToString();
sd.Rate = dr["rate"].ToString();
bislist.Add(sd);
}
Note sure how you displaing plus sign in your JS codes.
But here work-around is to escape the plus sign by preceding it with a backslash.
var data = dbrawdata.replace('+', '\\+');
It would be good to answer your question add some line of your codes.
As i understood
Very simple,
var value='2000+';
value.toString(); // => '2000+'
OR
String('2000+'); // '2000+'
Can somebody please help me understand what is going on in Getcookie function. I am trying to get my in-depth understanding of whats happening in every single line of code.
function Getcookie(name) {
var dc = ";" + document.cookie
var start = dc.indexOf(";" + name + "=")
if(start == -1) return false
start += name.length + 2 // Why is 2 being added here
var end = dc.indexOf(";", start)
end = (end == -1) ? dc.length: end
return decodeURI(dc.substring(start, end));
}
The only real question I see is "Why is 2 being added here".
The document.cookie looks like this:
name1=value1;name2=value2;name3=value3...
If name = "name2", start will be the index of ;name2= in that string, and we want to get value2. To get from the beginning of that string to the end, we add the length of name2, and then an additional 2 for the ; and = characters. Now start points just past the = character, which is the beginning of the value.
After that, we search for the next ; character and set end to its index. If it's not found, we set it to dc.length (you have a typo there, dec should be dc). Then the value is everything from start to end.
I am programmatically building a URI with the help of the encodeURIComponent function using user provided input. However, when the user enters invalid unicode characters (such as U+DFFF), the function throws an exception with the following message:
The URI to be encoded contains an invalid character
I looked this up on MSDN, but that didn't tell me anything I didn't already know.
To correct this error
Ensure the string to be encoded contains only valid Unicode sequences.
My question is, is there a way to sanitize the user provided input to remove all invalid Unicode sequences before I pass it on to the encodeURIComponent function?
Taking the programmatic approach to discover the answer, the only range that turned up any problems was \ud800-\udfff, the range for high and low surrogates:
for (var regex = '/[', firstI = null, lastI = null, i = 0; i <= 65535; i++) {
try {
encodeURIComponent(String.fromCharCode(i));
}
catch(e) {
if (firstI !== null) {
if (i === lastI + 1) {
lastI++;
}
else if (firstI === lastI) {
regex += '\\u' + firstI.toString(16);
firstI = lastI = i;
}
else {
regex += '\\u' + firstI.toString(16) + '-' + '\\u' + lastI.toString(16);
firstI = lastI = i;
}
}
else {
firstI = i;
lastI = i;
}
}
}
if (firstI === lastI) {
regex += '\\u' + firstI.toString(16);
}
else {
regex += '\\u' + firstI.toString(16) + '-' + '\\u' + lastI.toString(16);
}
regex += ']/';
alert(regex); // /[\ud800-\udfff]/
I then confirmed this with a simpler example:
for (var i = 0; i <= 65535 && (i <0xD800 || i >0xDFFF ) ; i++) {
try {
encodeURIComponent(String.fromCharCode(i));
}
catch(e) {
alert(e); // Doesn't alert
}
}
alert('ok!');
And this fits with what MSDN says because indeed all those Unicode characters (even valid Unicode "non-characters") besides surrogates are all valid Unicode sequences.
You can indeed filter out high and low surrogates, but when used in a high-low pair, they become legitimate (as they are meant to be used in this way to allow for Unicode to expand (drastically) beyond its original maximum number of characters):
alert(encodeURIComponent('\uD800\uDC00')); // ok
alert(encodeURIComponent('\uD800')); // not ok
alert(encodeURIComponent('\uDC00')); // not ok either
So, if you want to take the easy route and block surrogates, it is just a matter of:
urlPart = urlPart.replace(/[\ud800-\udfff]/g, '');
If you want to strip out unmatched (invalid) surrogates while allowing surrogate pairs (which are legitimate sequences but the characters are rarely ever needed), you can do the following:
function stripUnmatchedSurrogates (str) {
return str.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])/g, '').split('').reverse().join('').replace(/[\uDC00-\uDFFF](?![\uD800-\uDBFF])/g, '').split('').reverse().join('');
}
var urlPart = '\uD801 \uD801\uDC00 \uDC01'
alert(stripUnmatchedSurrogates(urlPart)); // Leaves one valid sequence (representing a single non-BMP character)
If JavaScript had negative lookbehind the function would be a lot less ugly...