Phantomjs Function.prototype.bind

2019-06-21 00:41发布

问题:

Yes, I know that. Function bind is not supported by Phantomjs. But maybe I can use something else, or say page.open not to use bind? It seems to be OK, but some websites return error

TypeError: 'undefined' is not a function (evaluating 'b.bind(a)')

After that I wrote a simple script, which just opens a page:

var address = phantom.args[0];
if(!address) phantom.exit(1);

page = require("webpage").create();

page.open(address, function(status){
setInterval(
   function () {

   console.log(
       page.evaluate(function() {
            return document.body.innerHTML.length;
       })
   )}, 200)
})

But error is still there. Error is not the main problem, but the problem is to get page content, because after error page content is not loading...

So, I need help.

P.S. Problem website is http://vkrushelnytskiy.wix.com/aaaa

回答1:

There is an npm package which loads a polyfill for phantomJS's missing .bind method. Copying the installation instructions here for convenience, but follow the link for any updates.

Installation

npm install --save-dev phantomjs-polyfill

Usage

require('phantomjs-polyfill')

Usage with Karma Include the polyfill directly in the files list of your karma.conf

...
files: [
  './node_modules/phantomjs-polyfill/bind-polyfill.js',
  ...
]
...


回答2:

You can use this code as an alternative

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}


回答3:

You can shim Function.bind using the following polyfill.

Just prepend it to the code you are trying to run. There are probably nicer solutions, but this worked great for me.



回答4:

You can mention this bind function just before the test case.

// PhantomJS doesn't support bind yet
Function.prototype.bind = Function.prototype.bind ||
  function (ctx) {
    var fn = this,
      args = [],
      param_length = 0;

  for(var i=0; i<arguments.length; i++) {    
    if(i){
      args[i-1] = arguments[i];
    }
  }
  param_length = args.length;
  return function () {
    for(var i =0; i<arguments.length; i++){
      args[param_length + i] = arguments[i];
    }
    return fn.apply(ctx, args);
  };
};