JavaScript: Saving/Loading cookies using HTML documents for a website - javascript

For school work I need to use JavaScript to Save and read a cookie. The code for setting the cookie is all good, I got it from w3Schools (I know it's a terrible guide apparently). My problem is getting it to work with HTML/notepad using the "path" thing going on.
When the webpage loads a function called checkcookie checks if the cookie exists, if it doesn't, it asks the user to enter their name and then saves a cookie for later. If a cookie already exists, it displays a greeting message :). So far, I have made the functions work on the example running interface thing that you can access on w3schools. However, I recently tried setting them up using HTML documents, and the cookies don't seem to save properly. I open a NotePad document, paste the code, save as HTML, and open with Google Chrome. The pop-up asks for my name, I enter, but when I reload, the pop-up asks for my name again, and again, and so on. Here is the page I got the functions from: http://www.w3schools.com/js/js_cookies.asp
I think I need to sort out a path for the cookie, or something, I looked at this webpage for more info http://www.quirksmode.org/js/cookies.html but I still don't understand.
Why does this not work? Should I set the path to the file directory which the webpage's html documents are saved in? Why does it work in the w3schools TryIt system but not with raw HTML documents?
function setCookie(cname,cvalue,exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname+"="+cvalue+"; "+expires+"; path=/";
}
function getCookie(cname) {
var title = cname + "=";
var cookie_array = document.cookie.split(';');
for(var i=0; i<cookie_array.length; i++) {
var check = cookie_array[i];
while (check.charAt(0)==' ') check = check.substring(1);
if (check.indexOf(title) != -1) {
return check.substring(title.length, check.length);
}
}
return "";
}
function checkCookie() {
var name=getCookie("name");
if (name != "") {
alert("Welcome again " + name);
} else {
name = prompt("Please enter your name:","");
if (name != null && name != "") {
setCookie("name", name, 30);
}
}
}

Yep, as mentioned by jyrkim is a webserver thing

Related

Is it possible to read ExperimentId and VariationId in Javascript with Google Optimize?

I have created an A/B-test using Google Optimize. Now I would like to read the current experimentId and variationId in Javascript. My goal is to run different javascript based on the given variation.
I can't seem to find any info on this in the documentation. Is it possible?
Now there is also the Google Optimize javascript API available that is a better option:
The experimentId is now available in the Optimize UI, as soon as the experiment is created (before start).
The API is already available in the page and you can use it like this:
google_optimize.get('<experimentId>');
(note: this will work only after the Optimize container script has been loaded)
You can also register a callback to run the javascript that you want at any time (even before the Optimize script has been loaded) using:
function gtag() {dataLayer.push(arguments)}
function implementExperimentA(value) {
if (value == '0') {
// Provide code for visitors in the original.
} else if (value == '1') {
// Provide code for visitors in first variant.
}
gtag('event', 'optimize.callback', {
name: '<experiment_id_A>',
callback: implementExperimentA
});
If you want to find both the experimentId and variation you can register a callback for any experiment:
function implementManyExperiments(value, name) {
if (name == '<experiment_id_A>') {
// Provide implementation for experiment A
if (value == '0') {
// Provide code for visitors in the original.
} else if (value == '1') {
// Provide code for visitors in first variant.
...
} else if (name == '<experiment_id_B>') {
// Provide implementation for experiment B
...
}
gtag('event', 'optimize.callback', {
callback: implementManyExperiments
});
For more details
https://support.google.com/optimize/answer/9059383
EDIT: Nevermind my cookie-based answer below, I found a better solution.
Just do this:
var propertyId = "UA-1234567-33";
var experimentId = Object.keys(gaData[propertyId].experiments)[0];
var variationId = gaData[propertyId].experiments[experimentId];
Old answer:
(Don't do this.. keeping it here for reference)
Maximes answer is working but was not exactly what I was looking for. I wanted to be able to find the experimentId and variationId without adding code through the visual editor. I finally found a way.
The values are actually stored in the _gaexp cookie. The cookie is present when an experiment is running. You can inspect it in Chrome by opening Developer tools, going to the Application tab and clicking Cookies in the left pane. It looks something like this:
GAX1.2.S1SJOWxJTVO9tM2QKV3NcP.17723.1
The experiment id is the part after the second number:
S0SJOWxJTVO1tM2QKD2NcQ
The variation id is the last number:
1
I wrote this code to extract it from the cookie:
function getCookieValue(cookieName) {
var result = document.cookie.match('(^|;)\\s*' + cookieName + '\\s*=\\s*([^;]+)');
return result ? result.pop() : '';
}
function getExperimentId() {
var cookie = getCookieValue('_gaexp');
if (cookie == undefined) {
return undefined;
} else {
var fields = cookie.split('.');
return fields[2];
}
}
function getVariationId() {
var cookie = getCookieValue('_gaexp');
if (cookie == undefined) {
return undefined;
} else {
var fields = cookie.split('.');
return fields[4];
}
}
var experimentId = getExperimentId();
var variationId = getVariationId();
WARNING: Fetching the experiment ID and variationId from the cookie is not a good idea. For two reasons.
When the experiment is finished, the cookie is still present. The cookie is cached, so you will find an experimentId and variationId that does not apply, and you can not know if the experiment is running or not.
If you stop experiment A, and start experiment B, the old value for A will still be part of the cookie. So it will look something like this:
GAX1.2.S1SJOWxJTVO9tM2QKV3NcP.17723.1!vr1mB2L2RX6kSI1ZnUDTzT.18721.0
which is the same as how it would look if you were running to experiments at once. It makes it hard to reason about what experimentId to use.
Google Optimize allow you to run arbitrary JS on a per DOM element basis.
This feature is meant to modify the DOM elements, but there's nothing stopping you from using it to call a JS function or define some variables.
How to set up the script
Edit your experiment variant in the Visual Editor.
Click on the Select elements icon (the rectangle in the top left corner)
In the Element Selector field, type in body.
Click the Add change button and select Javascript. This will bring up a dialog that allows you to input a JS function that will be called for the body.
Put in the code you want to run in there.
What code to run
Assuming you have a doSomething() method define on your page, you can have your Google Optimized function look something like this:
doSomething("Experiment #1", "Variant A");
Alternatively, you can try defining your variables globally.
// We need to use `windows` here, because if we define a variable
// with `var`, it will be limited to the scope of the Google Optimize
// function.
window["google_optimize_exp_id"] = "Experiment #1";
window["google_optimize_exp_var_id"] = "Variant A";
If you use the second method, keep in mind that you need to wait until the Google Optimized function has run before running your own logic.
There are a 3 ways you could do this:
1) Depending on your Google Analytics setup, you can access the following object via Chrome console and pass in your GA property ID:
Object.keys(window.gaData["YOUR-GA-PROPERTY ID"].experiments).forEach(function(key, index){
var value = window.gaData["YOUR-GA-PROPERTY ID"].experiments[key];
console.log("Info", key, value, index);
});
2) As someone has already pointed out, you can access the _gaexp cookie, which stores your experiment ID and variant number.
//READ THE COOKIE
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
};
// GET THE COOKIE
let getCookie = readCookie("_gaexp");
console.log('getCookie', getCookie);
// WILL RETURN A STRING IN THIS FORMAT
// GAX1.2.YOUREXPERIMENTID.18803.0
// The long number in the middle is your experiment ID
// The number at the end is your variant number (0)
// SPLIT THE COOKIE
let splitCookie = readCookie("_gaexp").split("!");
// SPLIT THE COOKIE SO YOU CAN ACCESS THE EXPERIMENT ID AND VARIANT NUMBER
3) And lastly, you could use your dataLayer.
A bit more of a clunky way to do it, but in Optimize 360, you could add JavaScript in each variant, (when you go edit your AB Test/variants). And send your experiment ID to your dataLayer, as well as other information.
EG:
function returnDate() {
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
var yyyy = today.getFullYear();
today = mm + '/' + dd + '/' + yyyy;
return today;
}
var dateToday = returnDate();
var ABTest = {
id: 'YOUREXPERIMENTID',
name: 'Title of your test',
description: 'Test description',
date: dateToday, //The launch date of AB Test.
variant: 1,
totalVariants: 5
};
// AND THEN PUSH ALL THAT INFORMATION INTO THE DATALAYER
dataLayer.Tests.push(ABTest);
Then to access all that information, all you need to do is access the window.dataLayer object.
Now how I've used google tag manager, add the "Test" key, in dataLayer.Tests. But of course you don't need that, but I just like to organise my object :)
I've found that the variant number can be obtained running a code like:
gaData["UA-XXXXXXXX-X"].experiments['ZYkOuNLKEoeLytt-dLWw3x']
The result should be "0"for the original, "1" for the first variant...
You can get the experiments with:
gaData["UA-XXXXXXXX-X"].experiments
Of course you have to replace UA-XXXXXXXX-X for the Google Analytics ID and ZYkOuNLKEoeLytt-dLWw3x for your experiment id.

How to save a javascript variable

I have a javascript variable, which is incremented by a javascript function in a .php script, only problem is that the page reloads when the function is called, so I need some way of saving the variable to be the same when the page is either reloaded or whenever you enter it.
I know you can do a local save but I am not quiet sure if it saves the variable when you leave the website.
My variable is in a html script.
<script type="text/javascript">
var varNumber= 1;
document.getElementById("varNumber").innerHTML = varNumber;
document.getElementByID("varNumber").value = varNumber;
function addToVariable() {
varNumber= varNumber+ 1 ;
document.getElementById("varNumber").innerHTML = varNumber;
}
</script>
Here are three client-side methods to save JavaScript variables across page refreshes and descriptions on how long they can persist data.
Saving a JavaScript variable with local storage
Saving a JS variable using local storage is easy and convenient with modern browsers.
var get = function (key) {
return window.localStorage ? window.localStorage[key] : null;
}
var put = function (key, value) {
if (window.localStorage) {
window.localStorage[key] = value;
}
}
To save and read an object instead of a simple variable:
localStorage.yourObject = JSON.stringify(obj);
obj = JSON.parse(localStorage.yourObject || "{}");
Persistence:
User agents may, if so configured by the user, automatically delete
stored data after a period of time.
For example, a user agent could be configured to treat third-party
local storage areas as session-only storage, deleting the data once
the user had closed all the browsing contexts that could access it.
This can restrict the ability of a site to track a user, as the site
would then only be able to track the user across multiple sessions
when he authenticates with the site itself (e.g. by making a purchase
or logging in to a service).
However, this also reduces the usefulness of the API as a long-term
storage mechanism. It can also put the user's data at risk, if the
user does not fully understand the implications of data expiration.
References:
http://dev.w3.org/html5/webstorage/
Persisting values in JavaScript object across browser refresh
How persistent is localStorage?
Saving a JavaScript variable with cookies
Saving a variable with cookies:
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
Persistence:
Session cookies - these are temporary and are erased when you close
your browser at the end of your session.
Persistent cookies - these remain on the client hard drive until they
are erased or expire.
This is ultimately user-dependent. They could be paranoid about
cookies and local storage, and set them to session-only or none at
all.
REF: Set cookie and get cookie with JavaScript
Saving a JavaScript variable with window.name
You could also use the window’s name window.name to store the information using a JavaScript session.
Persistence:
This only works as long as the same window/tab is used.
REF: http://www.thomasfrank.se/sessionvars.html
You can use localStorage on client side
<script>
localStorage.setItem("mykey",99); // set a variable
var varNumber = localStorage.getItem("mykey"); // retrieve variable
</script>
You could use AJAX to execute PHP, like:
<?php
session_start(); $r = array();
if(isset($_POST['holdNumber'])){ // assumes {holdNumber:numberHere} sent through AJAX
if(preg_match('/^\d+$/', $_POST['holdNumber']){
$r['heldNumber'] = $_SESSION['holdNumber'] = $_POST['holdNumber'];
}
else{
// holdNumber hack
}
}
elseif(isset($_POST['load'])){
if(+$_POST['load'] === 1){ // assumes sending {load:1} in AJAX
if(isset($_SESSION['holdNumber']){
$r['heldNumber'] = $_SESSION['holdNumber'];
}
else{
$r['heldNumber'] = $_SESSION['holdNumber'] = 0;
}
}
else{
// load hack
}
}
echo json_encode($r);
?>

javascript - read a seperate tab to check if it's open

I'm looking for a way to somehow read / check if another browser tab is open before opening the requested tab.
For example:
This is for my traffic exchange site, they just open mysite.com/surf.php and leave it viewing user's submitted sites in a frame. They earn points just for leaving that running.
Now lets say USER A has SURF PAGE A running fine and then opens SURF PAGE B then he has 2 mysite.com/surf.php running and earning double the points everybody else will earn.
What I want to happen is:
USER A has SURF PAGE A running fine and then tries to open SURF PAGE B which will check if another mysite.com/surf.php is already open and if it is to redirect the request for the 2nd surf page to another mysite.com/surf-error.php
So they can only ever have 1 mysite.com/surf.php running at any given time.
How would I go about doing this?
Browser windows on the same domain in the same browser can exchange some information via:
Cookies
Local Storage
Communication with a common server
You can use 1) or 2) to store some information about an active page and refuse to let other pages be active if one is already active.
But, the most reliable way to enforce policies like you are asking about is to use the actual server to enforce it. If users have a login, then code the server to only allow a logged in user to accumulate points for one site at a time.
Other than these options, if you want to enforce it all client-side, you would probably need a browser-plugin that could monitor all open browser windows (which I assume is not practical). You cannot do monitoring of multiple windows opened by the user from plain javascript in a web page.
when you start tracking time for someone set a session variable
session.trackingtime = true
when you check again to start tracking time make sure that value is set to false. When you stop tracking time set the variables to false.
I have done something very similar today. Just update the else if part to do a redirect in your case.
// helper function to set cookies
function setCookie(cname, cvalue, seconds) {
var d = new Date();
d.setTime(d.getTime() + (seconds * 1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
// helper function to get a cookie
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
// Do not allow multiple call center tabs
if (~window.location.hash.indexOf('#admin/callcenter')) {
$(window).on('beforeunload onbeforeunload', function(){
document.cookie = 'ic_window_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
});
function validateCallCenterTab() {
var win_id_cookie_duration = 10; // in seconds
if (!window.name) {
window.name = Math.random().toString();
}
if (!getCookie('ic_window_id') || window.name === getCookie('ic_window_id')) {
// This means they are using just one tab. Set/clobber the cookie to prolong the tab's validity.
setCookie('ic_window_id', window.name, win_id_cookie_duration);
} else if (getCookie('ic_window_id') !== window.name) {
// this means another browser tab is open, alert them to close the tabs until there is only one remaining
var message = 'You cannot have this website open in multiple tabs. ' +
'Please close them until there is only one remaining. Thanks!';
$('html').html(message);
clearInterval(callCenterInterval);
throw 'Multiple call center tabs error. Program terminating.';
}
}
callCenterInterval = setInterval(validateCallCenterTab, 3000);
}

How can I store a cookie in local storage with Javascript?

I have an app for Android (and hopefully later iPhone) that is based on Javacript and is made into an app using Phonegap/Applaud.
Unfortunately, setting and getting cookies is not working on Android, and this might be particular to the Android environment. I was advised that using "local storage" might be more reliable.
However, I knew nothing about local storage until this morning, and so I'm struggling to get aquainted. From what I gather, it's basically just another place to save data with a different syntax. For my situation, I don't think it gives me any advantages over cookies other than the fact that Android is forcing me to use it. As a result, I'm hoping I can still leverage my existing code for setting and getting cookies, and not have to take on a whole new approach.
Surely I can just do a test in my Javascript to see if there is local storage, and if so, store and retrieve my cookie data there, and if not, then just use cookies as normal?
Note 1: I searched Stack Overflow for similar questions, and there was this one which at first seems exactly what I'm talking about, but it's too terse so I can't parse it to know what I should do with it. Also, I think it assumes the presence of libraries and code that I don't think I have. I also looked at this question but I think it's doing the reverse of what I'm after.
Note 2: This is my current code for getting and setting cookies (procured from somewhere on the web. Up until the Android problem, was rock solid reliable):
function getCookie(c_name)
{
var c_start = document.cookie.indexOf(c_name + "=");
if (document.cookie.length > 0)
{
if (c_start !== -1)
{
return getCookieSubstring(c_start, c_name);
}
}
return "";
}
function setCookie(c_name, value, expiredays)
{
var exdate = new Date();
exdate.setDate(exdate.getDate() + expiredays);
document.cookie = c_name + "=" + escape(value) +
((expiredays === null) ? "" : ";expires=" + exdate.toUTCString());
alert("this is document.cookie: " + document.cookie);
}
Have a look at http://diveintohtml5.info/storage.html. The history might not be very interesting at all, but it at least provides an excellent link list to other tutorials in the further-reading section.
So, now to your code. The first thing to mention is that localStorage has no expire - it's persistent (until the user manually cleans everything). If you'd like to use some shorter storage, you might also use sessionStorage, which has the same interface but last only until the browser is closed.
Rephrasing your code is simple:
function getCookie(c_name) {
return localStorage.getItem(c_name);
}
function setCookie(c_name, value, expiredays) {
return localStorage.setItem(c_name, value);
}
localStorage behaves exactly like a regular Object.
localStorage.somekey = "My data"; // set
alert(localStorage.somekey); // get
delete localStorage.somekey; // unset
The only real difference between localStorage and any other Object is that it is pesistent. Any page from the same origin can access the values in the object, and they even survive if the browser is closed.
They are superior to cookies in every way for data storage, because they don't get sent to the server with every single request (although that's not to say cookies are useless - both have their advantages).
It's really simple ;)
I used the information in the other answers, so this isn't a different answer, but I just thought it would be helpful to others to see the complete code I ended up with. This can be pretty much dropped in as a replacement for using cookies (as I did). It tests for local storage, and uses that if present, and uses cookies if it isn't.
Note you'll probably want to take out the alerts when implementing it.
function getCookie(c_name)
{
if(typeof localStorage != "undefined")
{
return localStorage.getItem(c_name);
}
else
{
var c_start = document.cookie.indexOf(c_name + "=");
if (document.cookie.length > 0)
{
if (c_start !== -1)
{
return getCookieSubstring(c_start, c_name);
}
}
return "";
}
}
function setCookie(c_name, value, expiredays)
{
var exdate = new Date();
exdate.setDate(exdate.getDate() + expiredays);
if(typeof localStorage != "undefined")
{
alert("This place has local storage!");
localStorage.setItem(c_name, value);
}
else
{
alert("No local storage here");
document.cookie = c_name + "=" + escape(value) +
((expiredays === null) ? "" : ";expires=" + exdate.toUTCString());
}
}

Accessing cookies, hopefully in JavaScript

I am working on a Firefox add-on that will allow users (all of whom are part of a specific group; this add-on is very limited in audience scope) to see the status of their authentication cookie from the status bar. We all have to authenticate to access work-related sites, but we get no warning when the cookie expires, so this causes annoying and sometimes drastic interrupts in work flow. Eventually, this add on will allow us to submit our credentials from the status bar without having to go to do any reloads or redirects, but for now, I just want to see it show the status.
I have been looking at the Mozilla developer pages at nsICookie, nsICookie2, nsICookieManager, etc, and it doesn't make very clear sense how any of it fits into JavaScript or XUL or anything else.
Ideally, I'd just like a way for the JavaScript to go outside of the document and get the cookie string for a domain I specify. If I could do that, it would allow the code to possibly be ported over to other browsers (Safari and Chrome, in particular). But if this must be browser specific, then I would at least like to know the method for checking if the cookie exists in Firefox without any bells and whistles of setting or removing.
Simply put, I want a way to say:
if (cookieExists("sample.com", CookieName)) {
alert("You're signed in!");
} else {
alert('Go sign in, you fool!');
}
What is the easiest/most portable way of doing this (browser-side, of course)?
I have been looking at the Mozilla developer pages at nsICookie, nsICookie2, nsICookieManager, etc, and it doesn't make very clear sense how any of it fits into javascript or XUL or anything else.
access to all cookies from Firefox extension is possible and uses the nsICookieManager and nsICookie interfaces. From javascript code in your extension, you access the cookie manager with
var cookieManager = Components.classes["#mozilla.org/cookiemanager;1"].getService(Components.interfaces.nsICookieManager);
and than you can iterate through all stored cookies
var enum = cookieManager.enumerator;
while (enum.hasMoreElements()){
var cookie = enum.getNext();
if (cookie instanceof Components.interfaces.nsICookie){
// commands
}
}
now, when having reference to cookie object you can check its properties
cookie.host
cookie.name
cookie.value
...
defined in nsICookie interface. This code is Firefox specific and can be run as a browser extension or signed script. Hope my explanation helped a bit.
Below I present some links on using JS XPCOM interfaces in extensions:
JS XPCOM
Using cookies
you can use jquery plugin for cookie handling
http://www.stilbuero.de/2006/09/17/cookie-plugin-for-jquery/
or simply through javascript :
http://www.quirksmode.org/js/cookies.html
Here's a nice tutorial for working with cookies in javascript. Using the functions from that tutorial, you could probably do something like this:
if readCookie(yourCookieName != "") {
alert("You're signed in!");
else {
alert("Go sign in, you fool!");
}
Here are the cookie functions:
function readCookie(name) {
var ca = document.cookie.split(';');
var nameEQ = name + "=";
for(var i=0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1, c.length); //delete spaces
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return "";
}
function createCookie(name, value, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function eraseCookie(name) {
createCookie(name, "", -1);
}

Categories

Resources