How to handle the browser cache issue in Oracle JET web application - oracle

I am facing the cache issue whenever I do a new deployment, changes are not reflecting automatically. Always I have to go to the browser setting and clear the cache.
Is there a way to handle this issue automatically whenever I do the new deployment.

requirejs.config({
// Path mappings for the logical module names
paths: {
'knockout': 'libs/knockout/knockout-3.4.0',
'jquery': 'libs/jquery/jquery-3.1.1.min',
'jqueryui-amd': 'libs/jquery/jqueryui-amd-1.12.0',
'promise': 'libs/es6-promise/es6-promise.min',
'ojs': 'libs/oj/v3.2.0/min',
'ojL10n': 'libs/oj/v3.2.0/ojL10n',
'ojtranslations': 'libs/oj/v3.2.0/resources',
'signals': 'libs/js-signals/signals.min',
'text': 'libs/require/text',
'hammerjs': 'libs/hammer/hammer-2.0.8.min',
'moment': 'libs/moment/moment.min',
'ojdnd': 'libs/dnd-polyfill/dnd-polyfill-1.0.0.min',
'customElements': 'libs/webcomponents/CustomElements'
},
waitSeconds: 0,
// urlArgs will be appended at end of .js files
urlArgs: "v=1.33",
// Shim configurations for modules that do not expose AMD
shim: {
'jquery': {
exports: ['jQuery', '$']
}
},
config: {
ojL10n: {
merge: {
//'ojtranslations/nls/ojtranslations': 'resources/nls/menu'
}
}
}
});
You can update version (by changing urlArgs parameter in configuration) every time you deploy new code, thus every time new JavaScript file will be downloaded.

This can always be a problem during development. There are a couple of solutions.
1) Build into your app URL, a version string. Every time you publish a new version, change that number and the browser will pull new files
2) Set the cache control values on your server so that it doesn't cache anything from your app directory
3) Just do what you're doing with clearing browser cache. There are utilities that add a button on the browser bar to make it easier to get at.
I personally use the node http-server library to run my dev work and I use it's cache control arguments to make sure nothing is being cached.
http-server -c-1 -o
The above turns off caching and launches the browser from the current location (loading index.html if present)

With Chrome: if you open the Developer Tools (F12), on the Network tab you can check the Disable cache checkbox, which turns off caching, while the DevTools is open.
With Firefox: if you open the Developer Tools (F12), click the cogwheel icon ("Toolbox Options"), then in the "Advanced Settings" section, check the Disable Cache (when toolbox is open) checkbox.
Now there will be no caching in the browser. Might slow down stuff seriously...

Related

How do I clear local images from Electron's cache when using a preload script?

Edit: While I still do not understand the differences between the session and webFrame cache, webFrame.clearCache() can simply be called from the within the preload script.
Problem
I have an Electron application which involves renaming and reordering images on the local filesystem. This often results in files swapping their filenames which causes caching issues that are not resolved until the window is reloaded. I am unable to clear or disable the cache.
Methods that work (unsatisfactory)
Calling require("electron").webFrame.clearCache(); from within the renderer process. This is not a satisfactory solution as it requires nodeIntegration to be enabled. (The WebFrameMain class available to the main process does not have a clearCache method).
Checking "Disable cache" from Chrome DevTools. Obviously this is not a solution for production.
Methods that don't work
Clearing the session cache. I noted that the session cache size was always 0.
mainWindow.webContents.session.clearCache();
Clearing the session storage data.
mainWindow.webContents.session.clearStorageData();
Adding the following command line switches to the main process.
app.commandLine.appendSwitch("disk-cache-size", "0");
app.commandLine.appendSwitch("disable-http-cache");
Providing a session object with cache disabled when creating the window.
webPreferences: {
preload: path.join(__dirname, "preload.js"),
session: session.fromPartition("example", { cache: false })
}
There are clearly components to the caching system I do not understand. It seems that the session cache and webFrame cache must be two different things, and I can not find a way to access the later from the main process or without nodeIntegration.
A minimal project which shows this issue can be found here: https://github.com/jacob-c-bickel/electron-clear-cache-test. Clicking the button swaps the filenames of the two images, however no visible change occurs until the window is reloaded.
I am using Electron 13.1.4 and Windows 10 2004.
You can create a function to clearCache with require("electron").webFrame.clearCache(); and attach it to the windows object in your preLoad script, then use that in your isolated renderer.
Google "electron preload"
Yeah – webFrame is meant to be used inside the browser, so that's usually going to mean preload.js. You then can use Electron's Inter-Process Communication (IPC) techniques to expose that method globally on the window object, allowing use elsewhere in your app!
It's like you're carving out a path through each level of your app for access to the right functions.
Altogether, that will look like this:
preload.js:
import { contextBridge, webFrame } from 'electron';
export const RendererApi = {
clearCache() {
webFrame.clearCache()
},
};
contextBridge.exposeInMainWorld("api", RendererApi);
And then anywhere inside your rendering process:
window.api.clearCache();

How to force loading the current version of an offline-able web app?

I'm doing a tiny offline-able web app / PWA. It's meant to be opened from a home screen icon and mimic a regular app by loading entirely from a cache when offline.
The app is written using Vue and to accomplish the above I'm just using their PWA template and whatever it generates. To the best of my knowledge what this does is set up workbox using the GenerateSW plugin to precache everything in the Webpack build, and registers it using register-service-worker. That is, I have fairly little control out of the box over the fine details, it's meant to be a turnkey solution.
That said, I'm not sure how to actually load a new build of the application when it's available. The above can detect this - the generated SW registration file with my changes looks like this:
import debug from 'debug';
import { register } from 'register-service-worker';
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready(...args) {
log('App is being served from cache by a service worker.\n', ...args);
},
cached(...args) {
log('Content has been cached for offline use.', ...args);
},
updated(...args) {
log('New content is available; please refresh.', ...args);
},
offline(...args) {
log('No internet connection found. App is running in offline mode.', ...args);
},
error(error, ...args) {
log('Error during service worker registration:', error, ...args);
}
});
}
When I make a new build of the application, and I refresh the app in a browser, the updated() callback is executed, but nothing else is done. When I tried adding:
window.location.reload(true);
which should be a forced refresh, I just get a refresh loop. I'm assuming this is because the service worker cache is completely independent from the browser cache and unaffected by things like the above or Ctrl+F5. (Which makes the "please refresh" rather misleading.)
Since this is going to mimic a native app, and it's supposed to be a simple line-of-business tool, I don't really need to do anything more complicated than immediately reload to the new version of the app when an update is available. How can I achieve this?
Okay so the behaviour I've observed is that the update does happen automatically, it's just not obvious as to what the exact sequence of events is. I'll try to describe my best understanding of how the generated service worker works in the installed PWA scenario. I'll speak in terms of "app versions" for simplicity, because the mental model behind this is closer to how apps, not webpages work:
You deploy v1 of your application to a server, install / precache it on a device, and run it for the first time.
When you suspend and resume your app, it does not hit your servers at all.
The app will check for an update when it's either cold-started, or you reload the page, i.e. using the pull down gesture on Android.
(Possibly also periodically as the cached version goes stale, but I haven't checked this.)
Say you've deployed v2 of your app in the meantime. Reloading an instance of v1 of the app will find this update, and precache it.
(One reason why prompting the user to reload doesn't seem to make sense. Whatever the reloading is meant to accomplish has already happened.)
Reloading an instance of v1 again does absolutely nothing. The app remains running between reloads, and you'll just get v1 afterwards.
(Reason number two why prompting the user to reload is pointless - it's not what causes a new version of an app to load.)
However, next time you cold start your app - e.g. nuke it from the task switcher and reopen - v2 of your app will be loaded and I'm guessing v1 will get cleaned out. That is, your app must fully shut down so an update will load.
In short, for an application to be updated from v1 to v2, the following steps need to occur:
Deploy v2 to server
Refresh instance of v1 on device, or shut down and reopen the app.
Shut down and reopen the app (again).

Prevent external files in src of iframe from being cached (with CloudFlare)

I am trying to make a playground like plunker. I just noticed a very odd behavior on production (with active mode in Cloudflare), whereas it works well in localhost.
By iframe, the playground previews index_internal.html which may contain links to other files (eg, .html, .js, .css). iframe is able to interpret external links such as <script src="script.js"></script>.
So each time a user modifies their file (eg, script.js) on the editor, my program saves the new file into a temporary folder on the server, then refresh the iframe by iframe.src = iframe.src, it works well on localhost.
However, I realized that, in production, the browser always keeps loading the initial script.js, even though users modify it in the editor and a new version is written in the folder in the server. For example, what I see in Dev Tools ==> Network is always the initial version of script.js, whereas I can check the new version of script.js saved in the server by less on the left hand.
Does anyone know why it is like this? And how to fix it?
Edit 1:
I tried the following, which did not work with script.js:
var iframe = document.getElementById('myiframe');
iframe.contentWindow.location.reload(true);
iframe.contentDocument.location.reload(true);
iframe.contentWindow.location.href = iframe.contentWindow.location.href
iframe.contentWindow.src = iframe.contentWindow.src
iframe.contentWindow.location.replace(iframe.contentWindow.location.href)
I tried to add a version, it worked with index_internal.html, but did not reload script.js:
var newSrc = iframe.src.split('?')[0]
iframe.src = newSrc + "?uid=" + Math.floor((Math.random() * 100000) + 1);
If I turn Cloudflare to development mode, script.js is reloaded, but I do want to keep Cloudflare in active mode.
I found it.
We can create a custom rule for caching in CloudFlare:
https://support.cloudflare.com/hc/en-us/articles/200168306-Is-there-a-tutorial-for-Page-Rules-#cache
For example, I could set Bypass as Cache Level for the folder www.mysite.com/tmp/*.

Firefox addon remove not clearing local storage

In chrome when you install a extension it clears the local storage associated with that extension. This doesn't seem to be the case for Firefox.
The only possible solution I can find is
https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Listening_for_load_and_unload
To listen for the 'install' event and clear it manually.
The problem Im having with this is that at the time main.js gets this event, my page-workers are already unloaded. I need to clear local storage which main.js cannot. So I need to emit to the page-worker so it can do so but the page-worker is already unloaded at this time.
The Firefox add-on SDK doesn't integrate with HTML5 local storage. So one solution is to use message passing and simple storage instead, then it should be wiped for you, as expected.
If it isn't, in main.js, you can simply write:
const { storage } = require('sdk/simple-storage');
exports.main = function({ loadReason }) {
if (loadReason==='install') for (var prop in storage) delete storage[prop];
}
If you need to use localStorage, store an array of affected pages in simple storage, then create a page-worker for each site on install and clear localStorage from each new content script.

Set firefox profile with protractor

I want to run tests with Firefox/protractor with the cache feature disabled.
(Actually, I'm trying to prevent 304 HTTP responses).
There are multiple ways to do this:
Disable the cache from the backend-side by droping Etag headers -> I can't modify the backend
Drop the Etag header from the frontend-side -> I tried, it did not work
Disable the cache from firefox: I just have to set the flag network.http.use-cache to false
Manually it works. I receive only 200 responses and it's great.
I want to be able to set this flag through protractor configuration. After some search I found out that I had to create a custom profile and set it in protractor this way (https://code.google.com/p/selenium/wiki/DesiredCapabilities):
capabilities: {
browserName: 'firefox',
firefox_profile: 'support/firefox_profile'
}
The problem is that the firefox profile is not considered. Is it the right option?
Do you have a better idea?
Thanks for your help.
EDIT:
As someone (suggested
capabilities: {
prefs: {
'config.http.use-cache': false
}
}
It did not work - I checked in about:config, the flag was still enabled.
How do you know what options you can pass in the capabilities?
Here's an example of how to integrate firefox-profile with protractor: https://github.com/juliemr/protractor-demo/tree/master/howtos/setFirefoxProfile
EDIT: For those upgrading to protractor >=1.6, the old way of doing this was broken because 'browser' can no longer return a promise. The demo has been updated.

Resources