Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diary - ways for fetching 3rd party scripts #2

Open
sashafirsov opened this issue Jan 30, 2018 · 14 comments
Open

Diary - ways for fetching 3rd party scripts #2

sashafirsov opened this issue Jan 30, 2018 · 14 comments
Assignees
Labels
diary question Further information is requested

Comments

@sashafirsov
Copy link
Member

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

  • IFRAME , but it will need a layer to run EPA integration API within embedded page
  • closure with wrapped window, document and other browser APIs to insulate related data layers from page itself and other EPA instances.

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

@sashafirsov sashafirsov added question Further information is requested diary labels Jan 30, 2018
@sashafirsov
Copy link
Member Author

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

  • same-origin gives direct messaging API
  • cross-domain The frame security restrictions prevent direct messaging leaving just a
    • server side peering
    • WebSockets/WebRTC broadcasting promise peer-to-peer model. Complains are on complexity side.

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
Copy link
Member Author

sashafirsov commented Jan 30, 2018

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
Copy link
Member Author

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
Copy link
Member Author

'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
Copy link
Member Author

Samples of embedded content

For now two extreme cases:

  • included into demo page. As served from same server, no issues on cross-origin, https, cors. It uses just one method of document as JS insulation show case.
  • real-estate site. Most complex case with multiple 3rd party scripts, served over HTTPS from own domain.

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.

  • ApiFusion.com could be the one.

@sashafirsov sashafirsov self-assigned this Feb 2, 2018
@sashafirsov
Copy link
Member Author

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
Copy link
Member Author

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 content will be embedded into EPA Container
  • API rev.#
  • Microapp authorization (API Key, etc.)
  • CMS Embedding mode ( as icon, tile, list element, list, preview, full page, full screen, site-page-instance config)

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
Copy link
Member Author

sashafirsov commented Feb 4, 2018

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
Copy link
Member Author

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

  • include the code sniplet and links to source where the code is used

@sashafirsov
Copy link
Member Author

sashafirsov commented Feb 10, 2018

The demo should highlight the insulation aspect. Hence provide

  • demo of multiple instances using the same code which do not affect each other
  • demo of same code not affecting the host page, use same elements in host page
  • demo of host code not affecting the APE components

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

@sashafirsov
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member Author

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 ?

  • setup click/tap/beforesubmit handlers and preserve url
  • magic to get URL from iframe attribute

Tricks to be evaluated:

  • on activation capturing phase prefix the URL with hash '#'. Which will

    • trigger the iframe url but its content could post the URL back to container, or
    • onload event on container itself.
  • is there "beforeload" event on iframe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
diary question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant