I use a library on my main site www.domain.com as such
<script src = 'lib.js'>
However, when I link out to another tab that points to ( using target = '_blank' )
www.domain.com/path
the library is gone and I have to reload it.
Is this expected behavior?
I thought because resources like localStroage have limits based on domain that other aspects of the environment would be domain based.
That is resources I load at www.domain.com I thought would be available at www.domain.com/path.
But this seems to not be the case.
Javascript files are only loaded for one page and need to be loaded again for every other page regardless of the domain or path.
Related
Background
In our company, we install our offline documentation topics (thousands of .htm files in a folder) on our users' computers. Users view our documentation offline through their browser using the file:/// protocol.
I have a banner that appears in the footer of each .htm file that asks users to decide whether we can track user analytics (via Application Insights). Once they make their choice, we don't show the banner.
My Goal and Overall Problem
My goal is to store their choice in the browser's local storage. I can do that just fine, but the problem is this:
These are offline .htm files. There is no website domain. So, the key and value for any local storage is stored only for the .htm file they are on at the time they make their choice. If they come back to a topic they made their choice on, then yes, my script can retrieve their choice. But if they navigate to another topic in our documentation system (another .htm file), the local storage key and value don't persist to those other topics, and my script doesn't know what they chose--so then the banner pops up again.
My Workaround Idea
I doubt this is the best approach, but not having a lot of experience and not knowing what else to try, necessity becomes the mother of invention.
Here's what I'm trying:
Have my local storage requests go through a single .htm file called storage.htm, thereby getting around the above problem by always having a single point of contact (storage.htm) with the local storage.
storage.htm loads via a blank iframe.
The iframe is tacked onto each .htm topic.
When a topic .htm loads, the iframe also loads and any functions inside it become (hopefully) available for use by my main script.
When users click on the banner, I send the choice as query parameters through my main script to the iframe's src.
storage.htm contains a parseQuery() function, and inside that function, it parses any query params and then does the actual localStorage.getValue(key) and localStorage.setValue(key,value) requests.
I then want to somehow force the iframe to refresh with those parameters and then call the parseQuery() function there from my main script.
My Code
From my main script:
Attempt 1:
I've tried the top-voted item from this thread,
How to check if iframe is loaded or it has a content?
but I get stuck inside the checkIfFrameLoaded() function, and it continues to loop through the check to see if the iframe is loaded. It never loads. I think it's because the contentWindow and/or contentDocument don't work with my offline files, so I won't bore you with that code.
Attempt 2:
This is what I'd like to do as it seems cleaner:
function doIframeStorage(type,key,value){
// We get a handle on the iframe's id of 'storage'.
let storage = document.querySelector('#storage');
const src = storage.getAttribute('src');
let query = src;
if (type==='get'){
query = src + `?type=${type}&key=${key}`;
} else if (type==='set'){
query = src + `?type=${type}&key=${key}&value=${value}`;
}
storage.src = query;
storage.addEventListener('load', (e) => parseQuery());
}
But I'm running into a problem where my parseQuery() function (from storage.htm) is always undefined:
Uncaught ReferenceError: parseQuery is not defined
Is it possible to load and access my parseQuery() function from my main script like I'm doing? If so, how? I thought the addEventListener would ensure it was loaded and therefore the parseQuery() function would then be available.
Or Is there a better way to do what I'm attempting?
Is it possible to determine that the loaded web resources like css, jscript, images, even the html itself are coming from cache or not using javascript ?
I'm trying to create a simple report on those loaded resources directly on on every pages i access in my development mode to avoid having to open up my google chrome debug tool every single time.
Though there are no direct way to figure out this using javascript, we can use a dirty workaround using windows.performance javascript API. Example given below
var fileToLookup = "http://sample.com/img/loader.png";
var isCached = Boolean(_.filter(window.performance.getEntries(),function(a){ return a.duration > 0 && a.name == fileToLookup }).length)
Here we are iterating the resources referred by the page and filtering by duration. If a resource taking > 0ms, we are assuming as not cached. Again, this is not foolproof method.
There are many solution to prevent the browser cache the resource, such as:
version number in filename (simple way for programmer, and not system admin)
Modify the Apache ETags
You can add a resource version number after the file name. Every time you modified the media file (Images/JS/CSS), you update the resource version.
<?php $resourceVer = '201404151859'; ?>
<script src='scripts/main.js?v=<?=$resourceVer?>'></script>
<link rel='stylesheet' href='style/main.css?v=<?=$resourceVer?>' />
Goal: the ?v=201404151859 is fake the browser there are different document of main.js, main.js?v=201404151859
I have the following function that activates when I click on some links:
function showPage(page) {
var History = window.History;
History.pushState(null,null,page);
$("#post-content").load(page + ".php");
}
The content of the page updates, the URL changes. However I know I'm surely doing something wrong. For example when I refresh the page, it gives me the Page Not Found error, plus the link of the new page can't be shared, just because of the same reason.
Is there any way to resolve this?
It sounds like you're not routing your dynamic URLs to your main app. Unless page refers to a physical file on your server, you need to be doing some URL rewriting server-side if you want those URLs to work for anything other than simply being placeholders in your browser history. If you don't want to mess with the server side, you'll need to use another strategy, like hacking the URL with hashes. That way the server is still always serving your main app page, and then the app page reads the URL add-on stuff to decide what needs to be rendered dynamically.
You need to stop depending on JavaScript to build the pages.
The server has to be able to construct them itself.
You can then progressively enhance with JavaScript (pushState + Ajax) to transform the previous page into the destination page without reloading all the shared content.
Your problem is that you've done the "enhance" bit before building the foundations.
In our current project, we're using HTML 5 localStorage with fall-back to global storage for Firefox and userdata behaviors for IE6/IE7.
The fall-back is provided through a JS script called jStorage.
This worked ok, until we started testing in IE6/IE7, even though it "works", it turns out that there's a restriction in userdata behaviour which locks it down so storage can only be set and read on the same URL or as MSDN puts it "For security reasons, a UserData store is available only in the same directory and with the same protocol used to persist the store".
Hence if I set a value on one page and then navigate to another, although I'm on the same site, it won't work.
Which for us pretty much renders it unusable as a fall-back for local storage, which is scoped per domain.
Has anyone come across this problem before and found a decent solution?
Any ideas or thoughts will be appreciated.
Remy Sharp's polyfill will do that.
https://gist.github.com/remy/350433
if the problem is to get data across two page in different paths, but in the same domain, you could try one of these (note: i didn't try: i'm just trying to be creative)
Use url rewriting (with an .htaccess) so you can access /path1/page1 and /path2/page2 with a single path-rewritten/page1 and path-rewritten/page2
if you are in /path2/page2 you could load an invisible iframe loading a page in /path1 in which you get the data stored in some data structure that you pass in the parent document.
Since page1 and page2 are - per hypothesys - in the same domain you can make the page1 and iframe communicate each other via javascript.
btw good question.
A theoretical solution would be:
dynamically create a hidden "proxy" iframe accessing a static
document retrieved from a location of your convenience, say
http:/domain/proxy.html
proxy access to the DOM element in the iframe to persist/fetch data
I currently have the following JavaScript function that will take current URL and concatenate it to another site URL to route it to the appropriate feedback group:
function sendFeedback() {
url = window.location.href;
newwin = window.open('http://www.anothersite.com/home/feedback/?s=' + url, 'Feedback');
}
Not sure if this is the proper terminology, but I want to mask the URL in the window.open statement to use the URL from the current window.
How would I be able to mask the window.open URL with the original in JavaScript?
Things you could do:
1- Mask the external site in a html frame inside a document from your site.
(for example www.mysite.com/shortUrl/)
2-Send a Location HTTP header (real url will eventually be displayed)
Keep in mind that browsers do their best to show the real address due to phishing concerns.
I wouldn't use javascript if I wanted to mask url even thought it would work with javascript. You wouldn't get much benefits in that scenario.
The reason is simple:
javascript/jQuery = functions belongs to client-side (browswer/your PC/DOM)
links, url, http, and headers = functions belongs to Apache.
Apache is always top level above client-side. Whenever link is fired to SampeLink.html, Apache wakes up and reads the file, but links/urls are already owned before javascript could claim them. So, it is kinda of pointless if you tried to manipulate links in your javascript scripts, even though it works but weak.
I'd point you to this awesome approach: .htaccess and you will be surprised how powerful it is. If .htaccess is presented in the parent folder of SampleLink.html, Apache denies the DOM engine (your browser) from reading files until Apache have finished reading .htaccess.
With your scenario, .htaccess can do some work for you by rewriting links and send "decoy" links to the DOM engine, meanwhile keeping the orginial links/urls behind the curtain; and visitors would reach to 404page if they tried to break the app or whatever you are concerned about.
This is a bit complicated, but it never ceased to fail me. I use this as my "bible" http://corz.org/serv/tricks/htaccess2.php.