Register service worker without access to local files - javascript

I'm attempting to build a PWA using Webflow, a web development tool. It is a web design platform, and it also manages hosting. It allows me to embed code into <head> or after the document, but it doesn't allow me to add any files to the server. I'm using a data: url to add a manifest file, which is working well. However, I'm finding it difficult to add a service worker.
I tried hosting the service-worker.js file on another server, and used navigator.serviceWorker.register('url_of_sw.js') but it gives me an origin error: ServiceWorker registration failed: DOMException: Failed to register a ServiceWorker: The origin of the provided scriptURL ('script_url') does not match the current origin ('site_url').
I tried a data: url by using navigator.serviceWorker.register('data:encoded_data') and it says that the protocol is not supported.
Is there any way to register a service worker without access to the local filestore? I know I can do it if I have control of a subdomain by setting document.domain. I want to assume I cannot do this.

This seems a browser security restriction. Just imagine, someone XSS this site, then all of the request will be control. It is dangerous.
Only service worker has this limit. For WebWorker, you can try:
const makeWorker = (workerFn) => {
const fnStr = `(${workerFn.toString()})()`;
const fnBolb = new Blob([fnStr]);
const fnUrl = URL.createObjectURL(fnBolb);
const worker = new Worker(fnUrl);
return worker;
};

Related

Ionic Refused to display 'https://withpersona.com/' in a frame because it set 'X-Frame-Options' to 'deny'

recently I have been implementing my Ionic App with Persona KYC. But I still have a problem with the integration. When I execute the javascript code in Ionic I get the error mentioned in the title. If someone can help me and the community to resolve this would be awesome.
Script:
function openClient(uid) {
const client = new Persona.Client({
templateId: 'itmpl_KxEjwiJXJMntb25dJXdrBnTP',
environmentId: 'env_gQDYrnzBZfXSiPWWdj4VSRGo',
referenceId: uid,
onReady: () => client.open(),
onComplete: ({ inquiryId, status, fields }) => {
console.log(`Completed inquiry ${inquiryId} with status ${status}`);
}
});
}
function cancelClient() { client.cancel(true); }
Typescript method calling the javascript function:
declare var openClient;
async openVerifyIdentityModal() {
if (!this.verifyIdentity) {
await openClient(this.auth.currentUser.uid);
await Preferences.set({ key: "verifyidentity", value: "true" });
}
}
Ed here from Persona. Thanks for sharing this - I asked our dev team to shed some light. Here's their suggestion:
Error: ReferenceError: self is not defined when using next.js
Error: Refused to display 'https://withpersona.com/' in a frame because it set 'X-Frame-Options' to 'deny'
ReferenceError: self is not defined when using next.js
The Persona JS SDK does not support server rendering. Add the following snippet:
TypeScript
import dynamic from "next/dynamic";
export const PersonaInquiry = dynamic(
() => import('persona').then((module) => module.Inquiry),
{ssr: false}
);
Refused to display 'https://withpersona.com/' in a frame because it set 'X-Frame-Options' to 'deny'
What this means
This error message is a result of a security feature that Persona offers when you integrate Persona using Embedded Flow.
Persona lets you specify, via an allowlist, which domains can load the embedded flow. You should specify only the domains where you embed your Persona flow. Potential attackers will then be blocked from embedding and loading your flow on their domain.
If you see this error, it means that the domain the embedded flow in being loaded on is not on the allowlist.
How to fix
If you see this error, go to the Embedded Flow integration page in the Persona Dashboard, and locate "Step 3 Configure allowed domains". Here, you'll see the Domain allowlist.
Ensure that:
The domain from which you are trying to load the Embedded Flow (and where you're seeing the error message) is on the Domain allowlist.
The domain in the Domain allowlist is correctly spelled and properly formatted. Note: a domain name should NOT include the http:// or https:// part of the URL.
If you are testing, please note:
If you want to load an embedded flow on localhost, you must use an embedded flow that points to your Sandbox environment. An embedded flow that points to your Production environment cannot be loaded on localhost.
If you have a more complex setup, please note:
If your embedded flow is loaded on a webpage that is itself loaded as an iframe on another parent webpage, you must specify all parent origins by setting the frameAncestors option in the JS SDK. See Parameters for details.
We also updated our support documentation to provide you with insights as to where to find a solution for this error message:
https://docs.withpersona.com/docs/troubleshooting-common-errors
Please reach out to our team on support#withpersona.com in case the suggested fix doesn't resolve the error.
Thanks,
Ed

Rewrite URL offline when using a service worker

I am making a web application with offline capabilities using a service worker generated by a Nodejs plugin called sw-precache. Everything works fine and I do have access to the html files or images offline.
But then, since you have no server-side language possible, is there a way to rewrite url client-side like an .htaccess file would do? Like showing a "404 Page not found" page when no file matches the url? I know that redirections are possible using Javascript or meta tags, but rewriting the url?
By default, sw-precache will only respond to fetch events when the URL being requested is a URL for a resource that it has cached. If someone navigations to a URL for a non-existent web page, then sw-precache won't respond to the fetch event.
That does mean that you have a chance to run your own code in an additional fetch event handler that could implement custom behavior, like returning a 404.html page when a user navigates to a non-existent page while offline. You need to jump through a couple of hoops, but here's how to do it:
// In custom-offline-import.js:
self.addEventListener('fetch', event => {
if (event.request.mode === 'navigate') {
event.respondWith(
fetch(event.request)
.catch(() => caches.match('404.html', {ignoreSearch: true}))
// {ignoreSearch: true} is needed, since sw-precache appends a search
// parameter with versioning information.
);
}
});
// In your sw-precache config:
{
// Make sure 404.html is picked up in one of the glob patterns:
staticFileGlobs: ['404.html'],
// See https://github.com/GoogleChrome/sw-precache#importscripts-arraystring
importScripts: ['custom-offline-import.js'],
}
This shouldn't interfere with anything that sw-precache is doing, as it will just be used as fallback.

I do not understand why this worker cannot spawn a sub-worker in IE10 HTML5

I have a Worker.js file and a Subworker.js file in my Scripts folder. No problem creating a worker, I can step through its code in the debugger; but when I want that worker to spawn a subworker, it isn't getting created, and I'm unable to step through the subworker code file in the debugger.
In myPage.htm script block:
var worker = new Worker("Scripts/Worker.js"); // Succeeds
In Worker.js script file:
var subworker = new Worker("Subworker.js"); //without the folder name FAILS
The IE10 developer tools Network console shows this:
URL....................Method...Result..Type.......................Received.......Taken......Initiator
/Scripts/Worker.js.....GET......200.....application/x-javascript...1.00KB..........<1ms......webworker
/Scripts/Subworker.js..GET......404.....text/html..................2.50KB..........239.29s...webworker
EDIT: Found the answer to the 404 error although still unable to instantiate the subworker:
var subworker = new Worker("..Subworker.js");
EDIT2: Also found that the following trick to cause the current version of a script to be used generates a 400 error:
var subworker = new Worker("..Subworker.js?version=2.0");
I'm in about the same boat.
My plan is to load a subworker from another doamin or file:// protocol because you cannot load one directly from a regular js script. I still need to test this, but I know that Workers/SharedWorkers are not subject to the normal Cross-Origin Restriction Policy, except** for when you're trying to load one (and hopefully only when doing this from a window script).
Another method is to use window.postMessage to forward messages to a Worker that it has created in the other window.
Alternatively, for my specific needs I am considering running a headless browser locally, a CDN, or a localhost "forever-server" with CORS enabled -- but this most likely still requires a window.postMessage().
Hope this helps, Tim!
Post back if you find an answer, eh?

Can I load a web worker script from an absolute URL?

I haven't been able to get something like this to work:
var myWorker = new Worker("http://example.com/js/worker.js");
In my Firebug console, I get an error like this:
Failed to load script:
http://example.com/js/worker.js
(nsresult = 0x805303f4)
Every example of web worker usage I've seen loads a script from a relative path. I tried something like this, and it works just fine:
var myWorker = new Worker("worker.js");
But what if I need to load a worker script that's not at a relative location? I've googled extensively, and I haven't seen this issue addressed anywhere.
I should add that I'm attempting to do this in Firefox 3.5.
For those that don't know, here is the spec for Web Worker:
http://www.whatwg.org/specs/web-workers/current-work/
And a post by John Resig:
http://ejohn.org/blog/web-workers/
Javascript, generally, can't access anything outside of the url that the javascript file came from.
I believe that is what this part of the spec means, from: http://www.w3.org/TR/workers/
4.2 Base URLs and origins of workers
Both the origin and effective script origin of scripts running in workers are the origin of the absolute URL given in that the worker's location attribute represents.
This post has a statement about what error should be thrown in your situation:
http://canvex.lazyilluminati.com/misc/cgi/issues.cgi/message/%3Cop.u0ppu4lpidj3kv#zcorpandell.linkoping.osa%3E
According to the Web Worker draft specification, workers must be hosted at the same domain as the "first script", that is, the script that is creating the worker. The URL of the first script is what the worker URL is resolved against.
Not to mention...
Just about anytime you have a Cross-Origin Restriction Policy, there's no counterpoise to the file system (file://path/to/file.ext) - Meaning, the file protocol triggers handling for this policy.
This goes for "dirty images" in the Canvas API as well.
Hope this helps =]

How to include custom JS in AMP Page through SW?

We have gone through from all possible blogs of AMP but couldn't find any way to include custom JS in AMP. This blog(https://www.ampproject.org/docs/guides/pwa-amp/amp-as-pwa#extend-your-amp-pages-via-service-worker) indicates that we can add Custom JS in AMP with the help of Service worker but haven't describe how to do it.
Please let us know How to do it.
Edit:- After adding JS at the run time, it again show the same old error, Please have a look to the image
Note in the mentioned blog post that you can extend your AMP pages
as soon as they’re served from the origin
Having a service worker in itself doesn't exempt you from AMP restrictions. However if you install a service worker in your AMP page, you can then begin to use AMP as a (progressive) web app, with less restrictions. There are multiple patterns you can use - this article covers the major patterns and this Google Codelab shows you how to implement them.
Hope that helps!
EDIT:
Yeah, okay I see what you mean. You could accomplish that by adding this code to the service worker:
self.addEventListener('fetch', e => {
var url = new URL(e.request.url);
if(url.pathname.split('/').pop().endsWith('amp.html')) {
e.respondWith(
fetch(e.request).then(response => {
var init = {
status: 200,
statusText: "OK",
headers: {'Content-Type': 'text/html'}
};
return response.text().then(body => {
body = body.replace('</body>', '<script src="extra.js" async ></script></body>');
return new Response(body, init);
});
})
);
}
});
This will dynamically add the extra.js file to all the *amp.html pages that your app requests. I believe it will still validate, but I haven't tested it.
Note that this will only work when it's served from your origin (as opposed to the AMP Cache), because that's where your service worker has control.
This resource is where I found the code example (it has a soft paywall).
Let me know if it works! :)
#DavidScales's answer is great if you want to specifically include your custom JS through a service worker for some reason. You could also just include your custom JS in a hidden amp-iframe on the page. Note that all of your custom js would have to be changed to reference the parent, so that it can access the AMP page's DOM.
See this thread.
Also see this thread for how to access the AMP page from inside the iframe.
The amp-install-serviceworker component enables service worker installation via same origin or via the Google AMP Cache.
Note : Service Workers are currently available in Chrome, Firefox and
Opera.
How to use amp-install-serviceworker? CLICK HERE

Categories