Force refresh doesn't work for Head JS - javascript

When scripts are loaded via Head JS I am unable to force the content to refresh using the Ctrl+F5 (or equivalent) keyboard shortcut.
The scripts cache correctly and the browser obeys the cache directives sent from the server (I'm using IIS 7.5). But unlike scripts tags included directly in the markup, I can't override the cache and force a refresh of the scripts loaded via Head JS.
I'm assuming this is a consequence of the way the scripts are loaded dynamically. I can live with this behaviour because forcing the refresh is only convenient during development, and I know of other ways I can force the content to be retrieved from the server.
I just wondered if anyone could explain why this is the case...
Update
This was never a problem for us in Live, because the cache directives for our static content were set appropriately. It was only ever a problem in Development and QA, The options left available to me were...
Configure all Dev and QA browsers to never cache content.
Configure the static content cache directives differently for Dev and QA environments - essentially setting MaxAge to something so small the content would always be expired. Only setting the correct MaxAge value in Live.
I went with the second option.

Dynamic script loading is not a part of the page loading proper. When you force refresh, the browser reloads the page and all resources referenced in its HTML and in referenced CSS files, but the scripts you load with head.js are not referenced in the page content and the browser has no way to figure out that head.js is going to create references to additional resources. At the point where these references are created, the browser is no longer refreshing the page and thus normal cache rules apply.
You can force reload of your scripts by appending unique query strings to their URLs (e.g. jquery.js?random=437593486394), but this will disable caching for all loads of your page, not just when you force refresh.

This is also a problem with require.js. Hopefully one of these work arounds will also apply to Head.Js
If using Chrome, open the developer tools panel on the Network tab, right click and choose 'Clear Browser Cache'
Do a bit of 'Cache-busting' by appending a datetime stamp to the query string for js resources
If your using IIS (which it looks like you are). Go to the HTTP Response Headers panel of your website, click Set Common Headers and set Expire Web content to immediately.
The latter is my preferred option for my development machine

I wouldn't say its a question of dynamic or not dynamic, when you inject a script it still causes the browser to make a HTTP request and apply whatever caching logic it applies.
Like mentioned above if you don't want scripts to be cached ..dynamic or static, it doesn't matter, you will usually have to append a timestamp in the form of a query string to it.
If you just want to see if you changes are working, do a force refresh in your browser ...usually CTRL+F5

Related

How do you properly handle caching static web content?

Browsers cache static files. It's what they're designed to do. 99% of the time, that's a good thing. Until we as developers update that static content.
If a developer updates a javascript file, but a user's browser pulls the cached version of it, then:
Best case, it'll be missing some new functionality until the browser decides to update its cache
Worse case, if you also updated the html page to call a javascript function that didn't exist in the older version of the javascript file that the browser cached, your page breaks
As developers, we know to hit Ctrl+Shift+R, or Ctrl+F5, or open dev console, disable cache on the Network tab, and reload. But users don't know that.
What is the best practice to handle updates to static content?
Is it to make sure that when you add new functions to a .js file, you push out the update to production a few hours/days before you update the html to call that function in <script> tags, allowing browsers to updated their cache over that time?
Is it to not call javascript functions from HTML within <script> tags at all?
Is there a way to somehow force browsers to expire cache on a specific static file when you update it?
Something else?
Obviously disabling all caching on your site is possible, but not a realistic solution.
PS. I'm not using any kind of frontend framework - just raw javascript/jquery. If the situation is different with frontend frameworks, I'd love to heard about that too at a high level
If I understand correctly, you want the JavaScript file to be updated for the user when you update. you should use service work API to create a cache version for specific files or use the Google workbox library. click here. for service worker API click here
Some years ago location.reload(true) allowed bypassing the cache like CTRL / Command+Shift+R does. Only Firefox continues to support this feature by now, but the hard reload using javascript is no longer supported on chromium based browsers. (spec doesn't describe this feature (anymore))
This change was also discussed on this issue on github/Microsoft/TypeScript and several other places on the web.
jQuery uses a simple workaround to be compatible with almost everything. If you load something with jQuerys jQuery.ajax({ url, cache: false }), it appends a _=TIMESTAMP parameter to the url, which has a similar effect but may bloat the cache.
You can make use of the Entity tag header (ETag). Entity tags are similar to fingerprints and if the resource at a given URL changes, a new Etag value must be generated by the server, which is a similar behavior to the Last-Modified header. (caniuse:etag)
Entity tags in: Apache, IIS, nginx (nginx docs), nodejs
It is also possible to clear the sites cache with a Clear-Site-Data: "cache" header. (mdn, caniuse:clear-site-data)

Is there any way to clear cache programmatically in angular 7 application?

I have a component which lazy loads the images.For the first time when my page loads then at that time the images are displayed using lazy loading but if I refresh or reload or close and then open the tab then my images are pre loaded because it is now fetched from cache.Is there any way i can stop caching of my component in angular 7?
The cache is not being done by Angular but your browser. Once you load an image (and depending on the headers of the response) your browser will cache it to be able to load it faster the next time. This is usually a good approach.
Not sure why you don't want them to be cached but you have different options. Here you have a good read about HTTP caching: https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching This cache configurations for static assets are usually done by your web server and they depend on which webserver you are using (nginx, Apache, IIS, node, ...).
Another option is to append a random query string to your image URL. This HTTP cache system works by using the image URL as a resource key to identify it. Because of this reason you can do something like:
<img src="./yourimagefolder/yourimage.jpg?r=putherearandomstring">
In this way your image resource 'Id' will be different in each request. (You will need to change the 'putherearandomstring' string in the example with a different random string each time the page is loaded.
If this is just for development purposes, you can disable the cache in developer tools. I don't see a reason you would want to do this for a live site though? As you would be forcing the user to grab the images everytime they load the component which will reduce performance.
The problem with cache in an environment where custom software is updated frequently and some users are less savvy is that they will not automatically get critical client-side changes unless they are told specifically to refresh their cache. With all of the decorations in the index.html I have not yet found a reliable solution.

Magento js and css changes not reflect

I had problem that i added custom java script its included but when i changes its contents it doesn't effect. it runs older java script file. since i cleared cache. i deleted every folder of /var/ also. but still it runs older java script code. while i see it in uploaded file also it shows updated code but using URL of that java script in browser it shows old code.
I flushed magento cache storage. flushed cache of css/javascript also.
In case if any guy have solution let me know.
Thanks in advance.
EDITED
Same problem with css also. Changes doen't reflect. cleared cache a lot of times from back-end as well as cleared var folder also.
Your server probably have header information asking browsers to cache static files like JS/CSS. It is likely that your browser is still caching the old CSS files. One way to check if it is indeed the browser and not say accidentally editing the wrong CSS file is by enabling and disabling (only go one way to check) the CSS file merge. By doing so you are forcing the browser to fetch for a whole new file - essentially bypassing caching.
You may also want to take a look at our CSS/JS Versioning extension which includes automatic refresh of the file name hash based on CSS/JS file timestamps (sensitive to editing and changes) http://extensions.activo.com/css-and-javascript-versioning.html
Have you cleared your local browser cache on your workstation?
Often, CSS and JavaScript can stick mightily and no matter now much you flush Magento caching on the server, the workstation browser never requests and downloads the new script. These are static files, a change in file date doesn't trigger browser reload, only complete removal from the browser cache does.
Usually CTL-F5 about three times will do it, otherwise you have to go into the web browser setups and flush browser cache there.
Also, if you're using JavaScript/CSS Merge, you need to click the button on the Cache Management page to Flush JavaScript/CSS Cache as well.
The only other place things can gum up is if you're running APC cache, you may need to flush it as well so the block caching for the head can refresh. This only matters if you changed the script and CSS file names, which you probably haven't, so it likely doesn't matter.

Wha is the meaning of this js.js?version=1364903356 in a webpage?

Every time i refresh a site and view its page source, the javascript src i.e js.js?version=1364903356; the version number always changes.
My question is: What is the meaning of this number; and if i put js.js in every page, the site is not working.
The version is generally appended for caching purposes, or rather, for invalidating the cache (by changing the version number, and hence, the requested URL), so it's seen as a new resources and downloaded afresh.
The number is probably meaningless. It is almost certainly just being appended to the URL so that the URL changes so the JS won't be fetched from the cache.
it's just for to avoid Caching purposes and request new each time. whenever you visit a same content. if you set static content caching enabled in IIS, then Browser will issue HTTP 304 not modified status to the resource.
you can view in chrome. open developer tools (f12) then go for network tab. you will see in request header like this.
Request Method:GET
Status Code:304 Not Modified
IIS/Any web server wil determine whether the content is changed or the same content. if the content is the same as resides in the cache then it will not iniitate the new request.
by appendign the version number, filename/url/resource will be changed. so browser will issue a new GET request for the resources.
This is a common technique used to prevent or manage caching of javascript and other files that the browser would normally cache.
If the version number always changes, then it means that the page in question is preventing your browser from caching the file at all; every request will load a new copy of the file regardless of whether it's changed or not.
This is poor practice, and likely due to a misconfiguration of the site in question.
More commonly, the version number would remain static, but could be triggered to change by the site itself. This would mean that for most requests the browser's caching would be in play, but that the site owner has control over whether to refresh the cache, for example when he updates the script file.
Without this technique, a browser that has already cached the old version of the file might not know that the file has been updated, and may not fetch the updated version. This could result in version conflicts between script files on the page.
There are, in fact, more technically correct ways of doing this that don't involve adding random values to the end of your URLs. The HTTP standard specifies that the browser should query the URL, and tell the site what version it has cached. The site can then respond with a "Not changed" message, and the browser can use the cached version. This ought to mean that the technique used in the question isn't necessary.
However, the technique is necessary in some cases because some browsers and/or web server configurations may not work correctly with the standard method, and the browser may still end up using the cached version incorrectly.
This technique can therefore be seen as a work-around for that.

How can I give users a javascript widget to pull content securely from my site

I need to be allow content from our site to be embeded in other users web sites.
The conent will be chargeable so I need to keep it secure but one of the requirements is that the subscribing web site only needs to drop some javascript into their page.
It looks like the only way to secure our content is to check the url of the page hosting our javascript matches the subscribing site. Is there any other way to do this given that we don't know the client browsers who will be hitting the subscribing sites?
Is the best way to do this to supply a javascript include file that populates a known page element when the page loads? I'm thinking of using jquery so the include file would first call in jquery (checking if it's already loaded and using some sort of namespace protection), then on page load populate the given element.
I'd like to include a stylesheet as well if possible to style the element but I'm not sure if I can load this along with the javascript.
Does this sound like a reasonable approach? Is there anything else I should consider?
Thanks in advance,
Mike
It looks like the only way to secure our content is to check the url of the page hosting our javascript matches the subscribing site.
Ah, but in client-side or server-side code?
They both have their disadvantages. Doing it with server-side code is unreliable because some browsers won't be passing a Referer header at all, and if you want to stop caches keeping a copy of the script, preventing the Referer-check from taking place, you have to serve with nocache or Vary: Referer headers, which would harm performance.
On the other hand, with client-side checks in the script you return, you can't be sure your environment you're running in hasn't been sabotaged. For example if your inclusion script tag was like:
<script src="http://include.example.com/includescript?myid=123"></script>
and your server-side script looked up 123 as being the ID for a customer using the domain customersite.foo, it might respond with the script:
if (location.host.slice(-16)==='customersite.foo') {
// main body of script
} else {
alert('Sorry, this site is not licensed to include content from example.com');
}
Which seems simple enough, except that the including site might have replaced String.prototype.slice with a function that always returned customersite.foo. Or various other functions used in the body of the script might be suspect.
Including a <script> from another security context cuts both ways: the including-site has to trust the source-site not to do anything bad in their security context like steal end-user passwords or replace the page with a big goatse; but equally, the source-site's code is only a guest in the including-site's potentially-maliciously-customised security context. So a measure of trust must exist between the two parties wherever one site includes script from another; the domain-checking will never be a 100% foolproof security mechanism.
I'd like to include a stylesheet as well if possible to style the element but I'm not sure if I can load this along with the javascript.
You can certainly add stylesheet elements to the document's head element, but you would need some strong namespacing to ensure it didn't interfere with other page styles. You might prefer to use inline styles for simplicity and to avoid specificity-interference from the page's main style sheet.
It depends really whether you want your generated content to be part of the host page (in which case you might prefer to let the including site deal with what styles they wanted for it themselves), or whether you want it to stand alone, unaffected by context (in which case you would probably be better off putting your content in an <iframe> with its own styles).
I'm thinking of using jquery so the include file would first call in jquery
I would try to avoid pulling jQuery into the host page. Even with noconflict there are ways it can conflict with other scripts that are not expecting it to be present, especially complex scripts like other frameworks. Running two frameworks on the same page is a recipe for weird errors.
(If you took the <iframe> route, on the other hand, you get your own scripting context to play with, so it wouldn't be a problem there.)
You can store the users domain, and a key within your local database. That, or the key can be an encrypted version of the domain to keep you from having to do a database lookup. Either one of these can determine whether you should respond to the request or not.
If the request is valid, you can send your data back out to the user. This data can indeed load in jQuery and and additional CSS reference.
Related:
How to load up CSS files using Javascript?
check if jquery has been loaded, then load it if false

Categories

Resources