ocLazyLoad icon indicating copy to clipboard operation
ocLazyLoad copied to clipboard

Make resources requests go through the interceptors chain

Open jdmichaud opened this issue 8 years ago • 4 comments

If I understand correctly, as ocLazyLoad is written today, lazy loaded resources (CSS or JS) are loaded directly through a browser managed GET request, not through the $http angular facility. Therefore, interceptors are not being fired for these kind of request, which is a problem to me.

Problem: I load resources for third parties. Those third parties basically write pages that I embed in my application. So at some point I will have a template, loaded from a templateUrl of a state that looks like:

<div oc-lazy-load="['$thirdPartyIdentifier$/some-directive.directive.js']">
  <pre>This is a third party page!</pre>
  <some-directive/>
</div>

I have an interceptor that catch all GET requests from my application and will replace $thirdPartyIdentifier$ with the appropriate URL. But for that particular case, this does not work, as explained above.

Would there be a way to modify ocLazyLoad so that it executes the interceptors on the requested PATH? Or just add an API to ocLazyLoad with it's own brand of interceptor which would help modify the URL before they are added to the DOM ?

jdmichaud avatar Aug 25 '16 08:08 jdmichaud

What is the maintainer(s) point of view on this? If this idea is considered worthy by the maintainer(s), I am willing to spend some time to implement it.

jdmichaud avatar Sep 16 '16 06:09 jdmichaud

Hello,

It's not possible because files are loaded through script tags added to the page. If we had to load them with $http we would have to use eval to execute the code and that is not possible because it's a huge security breach, and it might even be blocked by some configurations

But templates are loaded through $http, so this might work for you

ocombe avatar Sep 16 '16 07:09 ocombe

Yes templates are working OK, but the resources they are fetching are not.

What we can do is, when we build the element (buildElement), we just go through a list of modifier that would have been setup at configuration time, which takes the URL as provided in the template (path parameter of buildElement), performs modifications and return a modified string to be used as the URL.

function transformUrl(originalUrl) {
  var newUrl = // do something here...
  return newUrl;
}

$ocLazyLoad.load({
  interceptors: [transformUrl],
  ...
});

And then, in buildElement:

  $delegate.buildElement = function buildElement(type, path, params) {
    [...]
    const newPaths = params.interceptors.map(function (interceptor) {
      interceptor(path);
    }).filter(function (newPath) { // filter out interceptor which didn't do anything
      return newPath != path;
    });
    if (newPaths.length !== 0) {
      path = newPaths[0];
    }
    [...]
  };

jdmichaud avatar Sep 16 '16 08:09 jdmichaud

finally, i rewrite buildElement function to achieve this

idododu avatar Jan 21 '19 02:01 idododu