Replacement for window.sessionStorage in Javascript? - asp.net

I have an application with a launch page that needs to determine what is already opened, so it does not reopen things that are opened already in another new tab. In Firefox, I was able to make this work, by using window.sessionStorage to store the titles of pages that are open, and then use window.opener with the following code to remove the titles from the list.
Gecko Session Storage Info Page
if (window.sessionStorage) {
if (window.sessionStorage.getItem(code)) {
return; // page already open
}
else {
window.sessionStorage.setItem(code, code);
window.open("Sheet.aspx", "_blank");
}
}
And on the pages that are opened:
function signalPageExit() {
if (window.opener.sessionStorage) {
window.opener.sessionStorage.removeItem(
document.getElementById("runcode").childNodes[0].textContent);
}
This doesn't work in IE so I decided to use a cookie strategy, but the cookies were never successfully deleted from code on the dynamically launched pages, and therefore pages couldn't be reopened from the launch page once they had been launched until the cookie expired.
My second attempt was to define my own sessionStorage when it did not exist. That looked like this:
function setStoreItem(name, val) {
this.storage[name] = val;
}
function getStoreItem(name) {
return(this.storage[name]);
}
function removeStoreItem(name) {
this.storage[name] = null;
}
function sesStorage() {
this.storage = new storageData();
this.setItem = setStoreItem;
this.getItem = getStoreItem;
this.removeItem = removeStoreItem;
}
// storage object type declaration
function storageData() {
}
// IE 7 and others
else {
window.sessionStorage = new sesStorage();
window.sessionStorage.setItem(code, code);
window.open("Sheet.aspx", "_blank");
}
But it seems the real session storage is special, this ordinary object of the window did not stay alive across postbacks and therefore when my launch page posted back, the list of created page titles was wiped out.
So now I'm looking for a way to make this work. I have a launch page called scoresheets.aspx that creates dynamic pages based on user requests. These pages share a substantial amount of javascript code that can be modified to make this work.
I don't want to refresh the launched pages when a user tries to reopen them, but if there is some way to detect the titles of opened pages or some other way to use window.opener to communicate with the same persistence that sessionStorage has, I'd be glad to use it.

Eric Garside’s jStore plugin provides a jquery based api to several client side storage engines.

you should go with that cookie strategy and set those cookies to expire when the windows (tab) is closed. that should work across browsers.

Related

Server side detection iframe

Related issues:
Server-side detection that a page is shown inside an IFrame
I find weird that we can't apparently know from the server side if whether the page is loaded through an iframe. Most answers say that it's only detectable from the browser, I just don't get why.
In the browser, we have access to document.referrer which clearly indicates the url we come from. There is something similar on the server side using req.headers.referer.
I just tested it with a local iframe and I got the following results:
referer http://localhost:8888/tests/chatbotIframeIntegration // The page containing the iframe
referer http://localhost:8888/chatbot // The page displayed within an iframe
referer undefined // seems to be undefined sometimes, maybe due to HMR?)
I can definitely detect the url the request comes from. So, if I know what url my app should be running into, I can definitely have some logic that figures out whether I'm calling my server from an external website, can't I?
Also, it's quite weird that the browser uses referrer and the server uses referer (one r)...
I've gained more experience through experimentation, so here is what I've learned so far.
As I thought, we can resolve the referrer through document.referrer (browser) and req.headers.referer (server).
So, it's possible to detect whether the current referrer is different than what's our hosting server, and in this case we know the query comes from an iframe.
It gets trickier when you want to know, from the server side, if a page within your site has been loaded through an iframe within that same site. In such case, there is no way to automatically detect whether we're running the page from an iframe or not.
For instance, if you have an iframe on page /index that loads /page2 page, then you can't know, from the server side if /page2 was loaded from the iframe (on /index) or from navigating to /page2.
And that's why people say there is no way to know, from the server side, if a page was loaded through an iframe. Because it's uncertain.
Now, my actual need was a little different. I needed to know if my /page2 was loaded from another domain that my own (cross domain), and that is fairly simple to know, because the referrer will be different that my own domain, both on the server side and browser side.
It got a bit more complex with my integration tests, because I had a /tests/iframeIntegration page that contains an iframe which loads another page /page2, from the same domain. (relative url)
The point was to test whether the iframe integration worked as expected, and because it was running on the same domain, I couldn't resolve whether I was loading it through an iframe.
For this particular case, I added a /page2?iframe=true in the url. It's the simplest workaround I've found that works universally (browser + server).
Here are a few utility scripts:
import { isBrowser } from '#unly/utils';
import includes from 'lodash.includes';
/**
* Resolves whether the current web page is running as an iframe from another page
*
* Iframes are only detectable on the client-side
* Also, using iframe=true as search parameter forces iframe mode, it's handy when using an iframe from the same domain
* (because same-domain iframes aren't detected when comparing window.parent and window.top since it's the same window)
*
* #return {boolean}
* #see https://stackoverflow.com/a/326076/2391795
*/
export const isRunningInIframe = (): boolean => {
if (isBrowser()) {
try {
return window.self !== window.top || includes(document.location.search, 'iframe=true');
} catch (e) {
return null; // Can't tell
}
} else {
return null; // Can't tell
}
};
/**
* Resolve the iframe's referrer (the url of the website the iframe was created)
*
* Helpful to know which of our customer use our app through an iframe, and analyse usage
* May not always work due to security concerns
*
* #return {string}
* #see https://stackoverflow.com/a/19438406/2391795
*/
export const getIframeReferrer = (): string => {
if (isRunningInIframe()) {
try {
return document.referrer || null;
} catch (e) {
return null;
}
} else {
return null;
}
};

How to reload Page in blackberry cascades QML

in my blackberry cascades app I have created a page using qml that loads data from backend after making an API call and works fine. But after I move to next page and come back I need to reload the data. i.e perform the onCreationCompleted operation again. Also the Qt.pageDef shows undefined after I come back so I guess if I could reload the page, it would work fine. I'm new to blackberry cascades, can anyone tell me what should I do to reload this page again and re-initialise Qt.pageDef?
Page {
id: homePage
Container {
id:contactListView
//Some code to create listview
onCreationCompleted:
{
Qt.pageDef = contactListView;
fetchInfo();
}
fetchInfo()
{
//make api call and fill listview
}
}
}
Obviously, there are some part of code missing as you show us a Page but you seem to push a new page from a NavigationPane.
Add this to your NavigationPane :
onPopTransitionEnded: {
fetchInfo()
}

Prompt to save data if and when changes have been made

I am using asp.net and I need to display a prompt to the user if they have made changes to the web page, and they accidentally close down the browser.
The page could be anything from "Edit Profile" to a "Submit a Claim" etc.
How can I can display the messagebox, ensuring that it is displayed only if changes have been made (as opposed to, the user making changes, then undo-ing the changes, and shutting down the browser)
What I have done in the past is use some client side scripting which does this check during the onbeforeunload event....
var showPrompt=true;
var isDirty=false;
var hidePopup=false;
function onBeforeUnload() {
if (showPrompt) {
if (isDirty) {
if (hidePopup || confirm("Click ok to save your changes or click cancel to discard your changes.")) {
doSave();
}
}
}
showPrompt = true;
hidePopup = false;
}
ShowPrompt can be set to false when your clicking on an anchor tag which won't navigate you away from the page. For example <a onclick='showPrompt=false' href='javascript:doX()'/>
isDirty can be used to track when you need to save something. You could for example do something like $("input").onchange(function(){isDirty=true;}); To track undo's you might want to replace isDirty with a function which checks the current state from the last saved state.
HidePopup lets us force a save without confirming to the user.
That's very difficult to even touch without understanding what's on the page. If it's a few controls you capture value at page load and store them so you can later compare. If it's a complex page you'd need to do an exact comparison to the entire viewstate.
Typically you'd handle this type of situation by setting a boolean to TRUE the first time any change is made and disregard the user changing it back. If you're just trying to avoid accidential non-save of data the user should be smart enough to know they've "undone" their changes.
You can do this with javascript. See this question and either of the first two answers.

Capture ASP.NET Session Timeout in a GeneXus Application

I need to capture an ASP.NET Session Tiemout in a GeneXus X application generated in C#. When a user stay away from keyboard more than N minutes, I would like to request User/password once again without loosing data's changes in webform
You should consider just extending the session timeout in the server, that way you wont need to solve the problem in the first place.
If that's not an option you could make a user control that checks periodically if the session is active via ajax, example with JQuery (not tested):
$(function() {
setInterval(CheckSession, 10000); /*10 seconds*/
});
function CheckSession() {
$.get("/CheckSession.aspx", function(data) {
$("body").append("<p>" + data + "<p/>"); /*shows current user*/
if(data = "")
$("#loginform").fadein(200);
});
}
Where the CheckSession is a main/http proc that does something like
&httprespone.addstring(&websession.get('userid'))
And in the case that it is not, disable the screen buttons and somehow show the login form:
I've never tried this, but it seems possible.
An alternative would be to attach the session checking code to the submit button, should be simple enough in any javascript framework.

Accessing browser cookies from Flex

I'm building a Flex widget for a private vBulletin site, and the Flex widget needs to access an XML file on the vBulletin server in order to display data.
For security reasons, the XML URL will need to have the value in the bbsessionhash cookie passed along in the URL request from Flex. The Flex widget will be embedded in the private area that the user has logged into, so the Flex request will be coming from the same website the cookie is from.
Is there any way to access the cookies directly within Flex? I would prefer not to use ExternalInterface to grab the cookie data from JavaScript, as it could get a little messy (the templates are developed by a completely different dev team).
I have never tried this, but this library might just do the trick.
As per the flash or flex cookies are concern developer can use shared object which is one kind of cookie used for flex application.
The sample code snippet is as followes
import flash.net.SharedObject;
// get/create the shared object with a unique name.
// If the shared object exists this grab it, if not
// then it will create a new one
var so: SharedObject = SharedObject.getLocal("UniqueName");
// the shared object has a propery named data, it's
// an object on which you can create, read, or modify
// properties (you can't set the data property itself!)
// you can check to see if it already has something set
// using hasOwnProperty, so we'll check if it has a var
// use it if it does, or set it to a default if it doesn't
if (so.data.hasOwnProperty("theProp"))
{
trace("already has data! It reads: " + so.data.theProp);
}
else
{
so.data.theProp = "default value";
so.flush(); // flush saves the data
trace("It didn't have a value, so we set it.");
}
Accessing Flex SharedObject is NOT the same as accessing the Browser cookies, to access the browser cookies, you may use the ExternalInterface class, please check the following reference to see samples:
http://livedocs.adobe.com/flex/3/html/help.html?content=passingarguments_4.html
A reference of how to use and control cookies using JavaScript can be found here:
http://www.quirksmode.org/js/cookies.html
I would use the following Flex code:
var myCookie:String = ExternalInterface.call("getCookie('cookieName')");
And in the HTML I would add the following Javascript:
function getCookie(c_name) {
var i,x,y,ARRcookies=document.cookie.split(";");
for (i=0;i<ARRcookies.length;i++) {
x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
x=x.replace(/^\s+|\s+$/g,"");
if (x==c_name) return unescape(y);
}
}
If you require more help you could also check the Flex documentation.

Resources