I'm currently trying to implement calling the storage access API, but am having trouble nesting the call to requestStorageAccess in hasStorageAccess.
Here is an outline of the code - it's fairly standard:
requestStorageAccessAndServe() {
let thisObject = this;
var promise = document.hasStorageAccess();
promise.then(
function (hasCookieAccess) {
if (!hasCookieAccess) {
document.requestStorageAccess().then(
function successful() {
// reload iframe to run with cookie access
window.location.reload();
},
function fail() {
thisObject.serveContent(); // Code goes into here
});
} else {
thisObject.serveContent();
}
},
function (reason) {
thisObject.serveContent();
}
);
}
When clicking on the button to trigger this method, I always fall into that "fail" function, with no prompt appearing to request storage access.
Surprisingly, this non-nested code works perfectly:
requestStorageAccessAndServe() {
let thisObject = this;
let hasCookieAccess = !!document.cookie;
if (!hasCookieAccess) {
document.requestStorageAccess().then(
function successful() {
window.location.reload();
},
function fail() {
thisObject.serveContent();
});
} else {
thisObject.serveContent();
}
}
This code works - it reloads the iframe on the first request and then serves the data after another request on reload, but checking for cookie access by doing !!document.cookie is extremely hacky (what if there is no cookie data in the first place), and I'm more trying to understand what is going wrong here. Does anyone have any idea?
For a possible solution, is there any way I can force resolve document.hasStorageAccess() so I don't need to nest it?
Edit:
Forcing the promise to resolve did not help either. See code example:
async requestStorageAccessAndServe() {
let thisObject = this;
let hasCookieAccess = await document.hasStorageAccess();
if (!hasCookieAccess) {
document.requestStorageAccess().then(
function successful() {
window.location.reload();
},
function fail() {
thisObject.serveContent();
});
} else {
thisObject.serveContent();
}
}
Still goes into that "fail" function...
The problem here is that requestStorageAccess() requires user intent to be called. By nesting it in the hasStorageAccess() promise, that user intent (click) is obscured, and Safari rejects the request automatically.
To counteract this, I resolve hasStorageAccess on iframe load (since it does not require user intent), store this result in a class variable, and then if it resolved to false, I check requestStorageAccess on click.