ocombe / ocLazyLoad

Lazy load modules & components in AngularJS
https://oclazyload.readme.io
MIT License
2.63k stars 510 forks source link

Make resources requests go through the interceptors chain #340

Closed jdmichaud closed 1 year ago

jdmichaud commented 8 years ago

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 commented 8 years ago

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.

ocombe commented 8 years ago

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

jdmichaud commented 8 years ago

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];
    }
    [...]
  };
idododu commented 5 years ago

finally, i rewrite buildElement function to achieve this