EPA-WG / embed-page

Proof of concept for Embeddable Progressive Application - a microapplication container, a WebComponent acting as seamless IFRAME or html include
https://www.webcomponents.org/element/EPA-WG/embed-page
Apache License 2.0
17 stars 5 forks source link

Diary - ways for fetching 3rd party scripts #2

Open sashafirsov opened 6 years ago

sashafirsov commented 6 years ago

In order to make the EPA component alive its JS need to be run in insulated context and with insulated browser APIs. It is possible via

The thread bellow reflects the evolution of thinking around subject and ways to implement.

sashafirsov commented 6 years ago

IFRAME needs the EPA API implementation on container embeddable side along with host-child frame communication.

Disregarding of cross-frame communication layer there is need for JS injection within component content - add a single script (perhaps hosted on APE CDN). For generic 3rd party use it would be possible via EPA API injection proxy.

EPA API injection proxy is relatively simple. All it requires is to add a single script into app html taken from 3rd party site.

IFRAME in comparison with closure insulation seems to be stronger. But would it survive the IFRAME UX limitations? Resizing of container, zoom and scroll inside, etc. Dom embedding does not have UX side effects, but needs closure insulation developed to the level of all APIs used by app.

sashafirsov commented 6 years ago

closure insulation.

The biggest challenge resides on 3rd party JS retrieval and running in APE component closure scope.

CORS restrictions

are not applicable if script is included via SCRIPT tag, but it prevents to use a custom scope for container objects insulation. In order to retrieve script via ajax the app should enable

Access-Control-Allow-Origin:* Access-Control-Allow-Methods:GET HTTPS hosted page would restrict the contained apps to use HTTPS scripts.

The absence or CORS headers or serving the app from HTTP would break ajax. The way around would be the proxy which will elevate http to https and inject CORS headers.

fetch() and service workers

unfortunately could be used only when container and apps are within same-origin. The service worker from 3rd party domain, scope to 3rd party domain unfortunately prohibited by current implementations. The fetch(... { mode: 'no-cors'}) does not help with another domain.

sashafirsov commented 6 years ago

The first part of EPA API appear to be about JS URLs substitution rules. The embedded content JS needs to be served with CORS. If those are not given the proxy on host page will give such ability.

The array of RegEx with replacement expression or function would do the job.

sashafirsov commented 6 years ago

'redirects' URLs mapping

For sites which having the trouble with setting CORS headers on SCRIPT urls the proxy which will inject CORS headers will be the solution.

`<embed-page src="page-with-js.html" redirects=' [ { "from": "https://www.cahousefinder.com/listings-search/", "to":"/listings-search/"} , { "from": "https://www.cahousefinder.com/wp-includes/", "to":"/wp-includes/"} , { "from": "https://www.cahousefinder.com/wp-content/", "to":"/wp-content/"} ]'

`

The redirects attribute/property with JSON array of URL prefix from and to With a thought to be in line with current URL mapping proposals on WHATWG. Those are quite popular in AMD and other module loaders.

While at the moment mapping works just by prefix substitution, in the future it could be upgraded with RegEx or function for URL recognition and replacement.

Security considerations.

The JS insulation EPA module is using redirects mapping when loading scripts. Scripts do not meant to be altered and passed via proxy only to inject the CORS headers. To assure the JS integrity even passed via proxy, the SCRIPT in host page could use integrity arrtibute. EPA should validate the attribute if available.

In the sample above the https absolute URL is replaces with relative to host page URL. Which means the owner of page is responsible for altering the JS content. Should substitution to relative URL be enforced pattern or it is OK to replace one host with another? The CDN or sub-domain of same owner are quite valid cases, meaning the restriction could be harmful for valid use.

sashafirsov commented 6 years ago

Samples of embedded content

For now two extreme cases:

Of course the 100% coverage of most complex case most likely will not be reached. Perhaps the clean sample of EPA-compliant site should be the 3rd option.

sashafirsov commented 6 years ago

Server-side vs client side injection

Even the IFRAME approach still would need the JS injection for embedded page. Which could be achieved by altering the html header

sashafirsov commented 6 years ago

Copyright vs embedding customization conflict

From very beginning of EPA idea the legal conflict of interests between container and embedded application has bothered me. To present the microapp coherently with page content EPA Container would need to modify UX including UI and behavior. Of course, it goes against interest of EPA microapp vendor: giving extra burden on support, reusing and altering the copyrighted content from legal side, etc. Since the EPA Microapp by definition hoses own content into 3rd party app and serves same content as microservice the legal scope should not be much different and already accepted on industry level (refs TBD). The embedding protocol should give to Microapp vendor a set of flags that instructs:

The first flag along with EPA API version serves as agreement to provide the content for embedding. API version states the protocol; authorization will make sure the content is served under signed contract enforced by Microapp vendor; CMS embedding mode is necessary for unification of embedding and keeping the compatibility across multiple EPA Container vendors. The unification in general is essential part of EPA idea as it solves the current development support burden for multiple content vendors.

sashafirsov commented 6 years ago

responsive IFRAME

As an option for embedding EPA. search

The postMessage method safely enables cross-origin communication between component and container. The EPA should define the protocol of identifying the instances and their relations. As postMessage is URL-based (targetOrigin), that should be addressed in unified URL '*' is not acceptable.

sashafirsov commented 6 years ago

While the demo page has necessary code for proof concept, it should be visually presented.

sashafirsov commented 6 years ago

The demo should highlight the insulation aspect. Hence provide

For clarity include the demo page in IFRAME next to its sources.

sashafirsov commented 6 years ago

TBD iron-ajax as request API.

PROS: no need to implement complex API and binding

CONS: bring Polymer API dependency

The <iron-ajax last-response="{{variable}}"> bounds response to variable and the content could be delivered as <embed-page>[[variable]]<embed-page>

sashafirsov commented 6 years ago

browsingContext is the main subject to substitute in embed-page. Figuring out the available via JS capabilities.

Use of plugin could be the next step for in-browser implementation acceptance.

sashafirsov commented 6 years ago

seamless iframe attribute from one side is not considered for browser implementation anymore, and from another keeps links/form targets in parent browsing context which goes against the micro application needs.

sashafirsov commented 6 years ago

One of ways to handle browsing context change: use hidden iframe as a target for all A links and forms. On loaded or changed(?) event get its URL, and set embed-page src attribute to this url. IFRAME should be removed once URL is acquired.

The IFRAME content could have beforeunload handler to detect the intent and prevent URL load.

Q. How to get URL from beforeunload handler ?

Tricks to be evaluated: