PWA offline check - TypeError: Network request for [start_url] threw an error: Failed to fetch - progressive-web-apps

https://songbook.app/en?standalone=true - this page URL is already in cache - workbox still throws an error that it can't fetch it.
I've tried to add it to runtime cache using axios get request and also directly adding it to cache like this:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
caches.open('sb-runtime-cache-v1').then(function(cache) {
cache.match('/en?standalone=true').then(function(response) {
if (!response) {
cache.add('/en?standalone=true')
}
})
})
navigator.serviceWorker.register('/sw.js', {
scope: '/'
})
})
}
Could you help to figure out how to fix this issue?
Previously I've added this url to cache using axios get request and it worked, now it's broken, I believe after google "improved offline check".
If I use preCaching - error disappears, but I need it in runtime cache because I need to refresh response in cache after user signed in to app.
LMK if have to provide more details.

Related

Can't resolve Dropbox.com redirects with Axios or D3-fetch

I'm trying to fetch data in the browser from a Dropbox link: https://www.dropbox.com/s/101qhfi454zba9n/test.txt?dl=1
Using Axios this works in Node:
axios.get('https://www.dropbox.com/s/101qhfi454zba9n/test.txt?dl=1').then(x => {
console.log('Received correctly')
console.log(x.data);
}).catch(error => {
console.log('Error', error.message);
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.log(error.request);
}
console.log(error)
});
https://runkit.com/stevebennett/5dc21d04bbc625001a38699b
However it doesn't work in the browser (click the "Console" tab):
https://codepen.io/stevebennett/pen/QWWmaBy
I just get a generic "Network Error". I see the 301 Redirect being retrieved, which seems perfectly normal, but for some reason, it is not followed.
Exactly the same happens with D3: "NetworkError when attempting to fetch resource."
https://codepen.io/stevebennett/pen/KKKoZYN
What is going on?
This appears to be failing because of the CORS policy. Trying this with XMLHttpRequest directly fails with:
Access to XMLHttpRequest at 'https://www.dropbox.com/s/101qhfi454zba9n/test.txt?dl=1' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORS isn't allowed on www.dropbox.com itself.

How to control if PWA uses cached version or fetches latest version?

I have installed my PWA from Chrome and Firefox on Android, and from Safari on iOS. When I update my code on the website, I see quite different behaviour in the PWAs in terms of using older cached versions vs the newest one - Firefox-created PWA seems to require about 2-3 kill and restarts of the PWA, Chrome takes 5-6, and I couldn't get Safari-based PWA to start showing the newest version without deleting the PWA and re-adding to Home Screen from browser.
Is there a spec that defines the conditions under which a newer, non-cached version is fetched? After much reading, I disabled the registering of my service worker, which should have made the PWAs network-only (no service-worker cache) but I continue to get old versions of the site served up in the PWAs. A normal browser window also seems to require multiple deep refreshes to get the new version, so I assume there is something besides the service worker that determines this?
Consider the following code.I will break it in parts:
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
return fetch(event.request).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// IMPORTANT: Clone the response. A response is a stream
// and because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have two streams.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
});
Over here cached first strategy is used,whenever you reload the page a fetch event is triggered.
caches.match(event.request)
.then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
First it checks if the required request is available in the cache,if yes then it will return the response and won't fetch from network.
return fetch(event.request).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// IMPORTANT: Clone the response. A response is a stream
// and because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have two streams.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
Now if the file was not present in the cache then this block gets to network gathers the required files then respond with it an also save it to cache for further use.
Consider the case that you have a file sample.html and it is cached,now you make some changes to the file's code but the changes won't be seen on your browser because it will see that the sample.html(old) was already present in the cache and respond with it.
Few generalized considerations regarding SW and PWAs:
Once you register your Service Worker (SW), you have to un-register it to make it sure you get the latest/updated version, and you can do so in the application tab under service worker
and then
to make sure you get the latest/update version of you PWA. What else you can do on top of it is, you can change the object name of the cache storage like below:
.
As long as you keep the object name same as well as don't unregister the SW and clear the Cache storage either, you will have to refresh your website. There is also, hard reload/clear cache and hard reload option as well if you keep pressing the refreshing button of the browser for couple of seconds but it still doesn't work until you unregister your service worker. So, in short unregistering SW and clearing Cache storage manually or changing the name of the Cache storage object will do the trick. Like any other technology/asset there are pros and cons. This is one of the draw back of the PWA if we don't use it properly, your client will never get the latest version, or the time he will get it may be too late. Cheers:)

First ajax attempt miss authorization in header on iphone/ipad

We use windows authentication in our application and it is working fine on our test server. When we publish it onto Production environment (Google compute engine), every first ajax request (per URL) on iPhone/iPad (not matter chrome or safari) after user logon will fail(can not connect to the server). When we perform exactly same action again, it will success. Here is one of our ajax request:
$.ajax({
url: '#Url.Action("GridData")',
type: 'post',
data: {
JobName: $("#JobName").val(),
JobNumber: $("#JobNumber").val(),
},
success: function (data) {
...
},
error: function (xhr, textStatus, errorThrown) {
// first attempt in iPad/iPhone(no matter safari or chrome) will go to here
alert('#Params.AjaxErrorMsg');
},
complete: function() {
...
}
});
After debugging with mac, I found the first ajax call missing the content of Authorization but I have no idea why (this is working fine in any browser with computer version.) Also, I am not sending cross domain request. If I tried to manually put valid data of Authorization for the first ajax call, it will success. Any direction or suggestion will be appreciated. Thanks!

Token based authentication to Jasper reports failing when used with visualize.js

I am using Jasper 6.1 and configured my server to allow token based authentication. It works fine when i use token to login from browser. With the valid token, I am able to get into the system without entering username and password.
Now, I am integrating it with visualize.js in order to show reports on our application's web page. Below is request call :-
var authToken = encodeURIComponent("u=jsmith|r=admin|exp=20150831172506-0800|t=ABC");
visualize.config({
server: "http://localhost:8080/jasperserver-pro",
scripts: "optimized-scripts",
logEnabled: true,
logLevel: "error",
auth: {
token: authToken,
preAuth: true,
tokenName: "pp"
}}, function (v) {
$scope.v = v;
$scope.reportingInitialized = true;
$scope.$digest();
}, function (err) {
alert("Auth error! Server said: " + err.message);
});
However, on successful authentication it is not redirecting to success url but returning the below html with HTTP code 200. Due to which the Authentication is failing with the error message as "Unexpected token <".
Appreciate any help on this.
<head>
<title></title>
<meta http-equiv="refresh" content="0;url=home.html">
<script language="javascript" type="text/javascript">
window.location="home.html";
</script>
</head>
<body>
If your browser doesn't automatically go there,
you may want to go to the destination
manually.
</body>
</html>
Here is the resolution for this issue for other's benefit:
The jsonRedirectUrl was missing in the applicationContext-externalAuth-preAuth.xml
<property name="jsonRedirectUrl" ref="authSuccessJsonRedirectUrl"/>
Also following lines need to be removed from this file to have the report show up without any error:
<!-- marker disabling JIAuthenticationSynchronizer: pre-5.1 external auth config-->
<alias name="${bean.authenticationProcessingFilter}" alias="proxyAuthenticationProcessingFilter"/>
Above solution is tested and working on Jasper Server 6.1
I have installed JRS 6.1 and :
The
was already in the applicationContext-externalAuth-preAuth.xml
And I have commented the "alias..." line
But still, when I do refresh my report page, the report is not displayed. I have to delete my cookies so that the report appears.
Did it really work for you ?
We found that the problem was that the first request establishes a session. If you send a new token with the second request while the first session is still active then the request fails. You need to modify your application to either continue to use the same token for the browser session or you could logout the user before sending the second request.
This is the expected behavior with visualize.js authentication so here are 2 options which I have through of using in my application
Approach 1
Reuse authentication call as per visualize.js documentation
use visualize.configure
visualize.config({
auth: {
token: "token",
organization: "organization_1"
}
});
then use visualize function to serve report 1 and report 2
// report 1
visualize(function(v) {
v("#container1").report({
resource: "/public/Samples/Reports/06g.ProfitDetailReport",
error: function(err) {
alert(err.message);
}
});
});
// report 2
visualize(function(v) {
v("#container2").report({
resource: "/public/Samples/Reports/State_Performance",
error: function(err) {
alert(err.message);
}
});
});
Approach 2
This approach which is not desirable. every time you want to show a report do following
send login call
serve the report
send a logout call

WL.Client.Logout not calling its onSuccess or onFailure callbacks?

Using Mobilefirst Platform 7.1,
I have noticed that logout function has stopped working. I have a browser web app which has a logout button which triggers:
WL.Client.logout("MyAuthenticatorRealm", {
onSuccess: function(res) {
console.log("success server logout"); // Never called :(
WLAuthorizationManager.obtainAuthorizationHeader().then (
function(header) {
// I would reload the app here,
},
function(error) {
...
});
},
onFailure: function(res) {
console.log("failure server logout"); // Never called :(
}
});
But callbacks are never called.
I have checked the sample code from this tutorial and I can see the same thing happening too.
Is there something specific I need to add in 7.1? This used to work in 7.0
EDIT 2015/08/31
There is nothing in the server logs. The client web app seem to be doing a request to authorization/v1/authorization?client_id=XYZ&scope=-MyAuthenticatorRealm&isAjaxRequest=true&x=0.07530371774919331 which returns 200 success.
EDIT 2013/09/17
With the new version (7.1.0.00.20150913-2345) the callback is called! However now I get an exception:
Uncaught ReferenceError: WLAuthorizationManager is not defined
Is this the correct way to do the logout for the latest version? I am trying the "Desktop Browser"
There is a known issue currently in MobileFirst Platform 7.1
APAR PI47591 WL.CLIENT.LOGOUT DOES NOT WORK IN HYBRID PREVIEW
You can open a PMR with IBM to share your interest for this fix, and get updated.