Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect JS frameworks/libraries used in a page?

I'd like to be able to detect all the frameworks/libraries used by a page, to help understand when content is dynamically-generated etc.

I downloaded and unpacked the source for two Chrome extensions, Library Detector and Appspector. It looks like they simply call window.FUNCTION_NAME_HERE, for example:

'Backbone.js': function () {
  return window.Backbone && typeof(window.Backbone.sync) === 'function';
},
'Underscore.js': function () {
  return window._ && typeof(window._.identity) === 'function' &&
    window._.identity('abc') === 'abc';
},
'Spine': function () {
  return window.Spine;
},
'Angular': function () {
  return window.angular;
},
'Ning': function () {
  return window.ning;
},
'Zepto': function () {
  return window.Zepto;
}

etc.

I have a few questions:

  1. What are the identifiers for each framework (e.g. "Spine", "angular") called? Is there any way to retrieve this information via AJAX or otherwise, so I don't have to manually enter them?
  2. I don't really understand what window.angular means, besides that it returns either the angular object or None. I know that AngularJS has loaded if the angular function is accessible through the window object, but I'm not really sure what it even means to be a member function of the window.
  3. Why is the procedure for Backbone and Underscore different than all the others? How do you know which one to use?
  4. I tried running both extensions on the Uber homepage, which uses React, and neither of them detected React. When I tried to console.log(window), there wasn't a React object listed either. Why is this, and how can I still detect the framework in these cases?
like image 690
soylentqueen Avatar asked Nov 06 '15 02:11

soylentqueen


1 Answers

It looks like you have misunderstood how that code detecting libraries work, and of course that relates to understanding the window object.

In a browser javascript environment window is the global object. All variables are defined as properties of the global window object, unless they are defined within a function with the var keyword.

Let's say you visit a page that uses jQuery library, open the browser console and type jQuery. That should respond with a function, which jQuery is. Essentially jQuery is a variable defined in the global scope, and it is available as a variable by it's name, and as a property of the window object: window.jQuery.

What libraries do by default if you include them with <script> tag is define themselves as a global variable. So with Backbone.js you will have Backbone global variable defined for you, and it will be available as window.Backbone, because window is the global object.

Similarly, Angular will define angular global variable, Zepto will define Zepto, and so on.

For this reason you should be able to detect any library by the global variables it defines.

A caveat however, is that in modern javascript applications, libraries do not necessarily register a global variable. They may be defined within a scope (a function) of that application. For this reason checking window.Libraryname doesn't guarantee the page isn't using this library. And in fact it may be a very difficult task to detect a library in this case.

  1. There are too many frameworks/libraries, so it is up on you to create the list, or find anyone who maintains one. Then you would look into what global variables that framework defines, so you could look for them as the identifier of that framework.
  2. As I explained above, angular is the global variable, also available as window.angular. If you create a scoped angular variable, like function (){ var angular = "my angular"; }, you will still be able to get the global one with window.angular.
  3. It is possible that the maintainers of that code became aware of two or more libraries that define Backbone global variable. And only the Backbone we know about, includes the sync function. That might be the reason they additionally check that Backbone.sync is a function. They can't just check for the Backbone.sync function without checking for Backbone first, because on non-backbone pages that would cause error.
    Similarly, with Underscore, there might be many libraries that define global _ variable, so we can know for sure it is the Underscore library by checking one of it's methods in work.
  4. As I mentioned above, libraries will not necessarily define a global variable, in which case you will not be able to detect them automatically. As an example, in a modern javascript application, you could use a library as a dependency with Browserify, or RequireJS, in which case the library most likely will not register any global variables.
like image 147
Yura Avatar answered Oct 12 '22 10:10

Yura