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

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/*.

Related

Firefox web extension - read local file (last downloaded file)

Im creating a web extension and porting from XUL. I used to be able to easily read files with
var dJsm = Components.utils.import("resource://gre/modules/Downloads.jsm").Downloads;
var tJsm = Components.utils.import("resource://gre/modules/Task.jsm").Task;
var fuJsm = Components.utils.import("resource://gre/modules/FileUtils.jsm").FileUtils;
var nsiPromptService = Components.classes["#mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
....
NetUtil.asyncFetch(file, function(inputStream, status) {
if (!Components.isSuccessCode(status)) {
return;
}
var data = NetUtil.readInputStreamToString(inputStream, inputStream.available());
var data = window.btoa(data);
var encoded_data_to_send_via_xmlhttp = encodeURIComponent(data);
...
});
This above will be deprecated.
I can use the downloads.download() to know what was the last download but I can NOT read the file and then get the equivalent for encoded_data_to_send_via_xmlhttp
Also in Firefox 57 onwards, means that I have to try to fake a user action by a button click or something, or upload a file.
Access to file:// URLs or reading files without any explicit user input
isnt there an easy way to read the last downloaded file?
The WebExtension API won't allow extensions to read local files anymore. You could let the extension get CORS privilege and read the content directly from the URL via fetch() or XMLHttpRequest() as blob and store directly to IndexedDB or memory, then encode and send to server. This comes with many restrictions and limitations such as to which origin you can read from and so forth.
Also, this would add potentially many unneeded steps. If the purpose is, as it seem to be in the question at the moment, to share the downloaded file with a server, I would instead suggest that you obtain the last DownloadItem object, extract the URL (.url) from that object and send the URL back to server.
This way the server can load directly from that URL (and encode it on server if needed). The network load will be about the same (a little less actually since there is no Base64 encoding involved which adds 33% to the size), and much less load on the client. The server would read the data as a binary/byte data stream; about the same as if the data was sent directly from the extension.
To obtain the last downloaded file you would do the following from a privileged script:
browser.downloads.search({
limit: 1,
orderBy: ["-startTime"]
})
.then(getLastDownload);
function getLastDownload(downloads) {
if (downloads.length) {
var url = downloads[0].url;
// ... send url to the server and let server fetch the data from it directly
}
}
According to this support mozilla question.
(2) Local file security
Firefox limits access from pages on web servers to pages on local disk or UNC paths. [...]).
Which solution ?
Use local-filesystem-links firefox addon (not tested)
and/or
run a small local webserver on client side, supposing server was run with sufficient privileges, you may finally access any local content via http:// (but still cannot with file:///)

Chrome slow to load resources `(from disk cache)`

My site http://www.front-end.io configures the HTTP requests to load resources from cache with first priority. So my header will be like:
cache-control:max-age=315360000
ETag:W/"11913b-ks0rwRQM+ijHcl1HDuse3g"
Chrome indeed does not initiate any request (even 304) to the server, it loads from the cache directly:
It takes my Windows10 Chrome >400ms to load the js file from local disk.
My Ubuntu Chromium also takes >100ms.
But FireFox takes around 10ms only!
I found this question as well, Google Chrome load image from cache slower than download, but there are not explanations.
Could anybody help? Thanks.
Probably that is wrong timing information.
In order to Chrome Dev Tools such as Timeline display correct information you must disable extensions to exclude noise that they produce. Relevant excerpt from How to Use the Timeline Tool article by Kayce Basques:
Disable extensions. Chrome extensions can add unrelated noise to
Timeline recordings of your application. Open a Chrome window in
incognito mode, or create a new Chrome user profile to ensure that
your environment has no extensions.
Although some extensions can intercept resource requests in blocking fashion Grammarly is not one of those extensions. It doesn't have required webRequestBlocking permission specified in manifest file. Check chrome.webRequest page for more information.
If you measure time that took browser to get /vendor.61e0ab918e699695d3a3.js script from disk cache, compile and execute it you will see that it is pretty much constant regardless of whether Grammarly enabled or disabled. You can use code snippet below:
<script>var startTime = performance.now();</script>
<script type="text/javascript" src="/vendor.61e0ab918e699695d3a3.js"></script>
<script>
var endTime = performance.now();
console.log("Time: " + (endTime - startTime) + " [ms].")
</script>

How do we effectively click on a link using Selenium + php_webdriver + Firefox?

I was having lots of glitches with my tests using Codeception + WebDriver + Selenium + Firefox, so I decided to remove Codeception from the variables and do some tests directly using php_webdriver, to discover the problem wasn't in Codeception.
I tried to go to a page using 3 different methods:
// Click a link
$driver->findElement(WebDriverBy::id('inbox-navigation'))->click();
// Directly go to the address via URL
$driver->get('http://testing.mysite.net/#/messages');
// Click via javascript
$driver->executeScript("jQuery('#inbox-navigation').click();");
Of course none of them work and, doing it manually in my browser it works fine. The link appear as clicked, the url changes, but the related page (loaded via ajax) never gets loaded.
Here's the full source code I'm using to test this:
<?php
require __DIR__."/vendor/autoload.php";
$host = 'http://localhost:4444/wd/hub';
$driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox());
$driver->manage()->window()->setSize(new \WebDriverDimension(1280, 720));
$driver->get('http://testing.mysite.net/');
$driver->findElement(WebDriverBy::id('email'))->sendKeys('john#doe.com');
$driver->findElement(WebDriverBy::id('password'))->sendKeys('secret');
$driver->findElement(WebDriverBy::id('sign-in-button'))->click();
$driver->wait(10)->until(WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::id('inbox-navigation')));
$driver->findElement(WebDriverBy::id('inbox-navigation'))->click();
sleep(15); /// to make sure it wasn't too fast
$driver->takeScreenshot('screen.png');
var_dump($driver->getCurrentURL());
And this is the link changed to Inbox:
Also, manually executing jQuery('#inbox-navigation').click(); in console also works fine.

History issue combining WP7.5, phonegap and jqm

I have a phonegap app that uses jqm that works fine in android and ios.
Porting to WP7 i have an issue with the history, specifically history.back() (but also .go(-1) etc). This refers to going back in history where the previous 'page' was in the same physical html file, just a different data-role=page div.
using a jwm site in a regular browser is fine (with separate 'pages' in the same html file). Also, using history.back() when we go from one html file to another in the app is fine. It's the specific combination of WP7.5, jqm and PG.
Has anyone come across a solution for this? it's driving me crazy, and has been as issue since PG 1.4.1 and jwm 1.0.
EDIT 1: It's possible that the phonegap process of initialising the webview on WP7.5 somehow overrides the jqm history overrides, after they've loaded.
EDIT 2: definitely something to do with jqm not being able to modify the history. each time there is a 'page' change, history.length is still 0.
EDIT 3: When i inspect the 'history' object, i found there is no function for replaceState or pushState - i know jqm uses this for history nav, maybe that's the problem.
ok - this isn't perfect, but here's a solution (read: hack) that works for me. It only works for page hash changes, not actual url changes (but you could add a regex check for that). Put this somewhere in the code that runs on ondeviceready:
if (device.platform == 'WinCE') {
window.history.back = function () {
var p = $.mobile.urlHistory.getPrev();
if (p) {
$.mobile.changePage("#" + p.pageUrl, { reverse: true });
$.mobile.urlHistory.stack.splice(-2, 2);
$.mobile.urlHistory.activeIndex -= 2;
}
}
}

Ajax locally testing

I'm new to this Ajax thing. I wanted to try this
http://labs.adobe.com/technologies/spry/samples/data_region/SuggestSample.html
neat little Autosuggest form.
The form doesn't work when i save it locally.
Below there is a list of what i've done and used so far :
Firefox -> save pages as ..(index.html)
new folder ( test23 )
also saved the products.xml
opened index.html
change this line : var dsProducts = new Spry.Data.XMLDataSet("../../demos/products/products.xml", "/products/product", { sortOnLoad: "name" })
into : var dsProducts = new Spry.Data.XMLDataSet("products.xml", "/products/product", { sortOnLoad: "name" })
test failed :(
Can anyone help me out ?
AJAX requests cannot access the local file system, so requests like that will fail. You will need to have the page up on a webserver. If you want a local one, install XAMPP or something similar.
I just tried for like three minutes and got it to work at the first try (without images). you have to remember to get all the scripts and actually point to them in the main html file.
Don't forget the script tags on lines 41 through 43.
Kris
-- additions:
I tested on my Mac's local filesystem without any server using Safari as my browser. I have since deleted the files but could easily do it again and put the files up for download.

Resources