Skip to content
This repository has been archived by the owner on Jun 19, 2020. It is now read-only.

add features for asynchronous downloads #1373

Closed
wants to merge 1 commit into from

Conversation

jefleponot
Copy link
Collaborator

To solve asynschronous downloads that does work with phantomjs v2 (issue : Synchronous XHR causing zero byte file downloads #1342 ), there is a proposal PR

for @langholz and @istr , thanks to your specifications.

PS : operation synchronously javascript is simply an absurdity because it inhibits the language spirit.
PS : PS : Could it be possible that a great tools as CasperJS be written to use asynchronous methods
(http://phantomjs.org/api/webpage/method/evaluate-async.html)
We could use it in more domains like "chrome extension tabs" : https://developer.chrome.com/extensions/tabs#method-executeScript

Best Regards
jef

.. note::

since phantom 2.0.0 synchronous downloads are forbidden : By default async is true / For backward compatibilty async is false with phantom 1.x.x::

casper.start('http://www.google.fr/', function() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would never ever change the API behavior (i.e. default values) depending on the engine in use.

Mark this "obsolete / not recommended" in doc, throw a warning to the output when used and advise to use the newly created "waitForDownload" instead.

Better throw an error if used with an engine that does not support it than silently changing behavior here.

@istr
Copy link
Collaborator

istr commented Dec 10, 2015

@jefleponot Thanks a lot for this PR 👍 .

It seems that you have a regression with form selects in your patch. Some builds fail for receipt of JSON content.

Please:

  • have a look into what causes the regression(s) and fix it
  • lint the code (some builds fail due to linting)

I would never silently change the API behavior due to the engine version in use, though.
Could you re-work your PR along my proposal and

  • just keep behavior for the sync functions
  • mark them obsolete / not recommended in the doc and give a hint to use the new waitFor... functions instead?
  • maybe throw an error within the non-recommended functions when used with an engine that does not support them?

I would really like to integrate this PR into 1.1 because it is a major improvement.

@jefleponot
Copy link
Collaborator Author

your are totaly right. You would never ever change the API behavior (i.e. default values) depending on the engine in use. The code will now throw an error.

I find my regression trouble with meld diff-tools.
I will do my best to make a PR soon.

Thanks for all your brillant analyses.

@jefleponot jefleponot force-pushed the downloadAsync branch 3 times, most recently from 8f20934 to 4f406de Compare December 10, 2015 12:41
@jefleponot
Copy link
Collaborator Author

partial PR done. CU next time
could you help me @istr ? Only one test can't success.

Thanks in advance

Sorry it works now :-)
That is really curious

@istr
Copy link
Collaborator

istr commented Dec 10, 2015

Nice! Thanks a lot. Restarted the failing job (known intermittent popup bug).

Will review, ask a second collaborator for opinion and then merge.

@jefleponot
Copy link
Collaborator Author

I have done a lot of improvements of CasperJS for my web service supervision job, that I newer commit. if you are interested in lots of PR, it will valid them.

@istr
Copy link
Collaborator

istr commented Dec 10, 2015

@jefleponot Sounds good. Maybe it would be best to create separate feature branches to help make the different change-sets small.

Any improvement is welcome. Especially those that help to close the numerous open issues.

Thanks for your support.


Saves a remote resource onto the filesystem. You can optionally set the HTTP method using the ``method`` argument, and pass request arguments through the ``data`` object (see `base64encode()`_)::

.. note::

since phantom 2.0.0 synchronous downloads are forbidden : By default async is true / For backward compatibilty async is false with phantom 1.x.x::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PhantomJS instead please :)

@mickaelandrieu
Copy link
Member

@jefleponot great contribution ! some comments to address then. But I'm 👍 to merge this feature :)

@istr
Copy link
Collaborator

istr commented Dec 10, 2015

@mickaelandrieu thanks for quick review. :) Maybe let's discuss the question:

  • silently change API behavior based on engine in use

vs.

  • warn the user she's trying to do something that won't be supported in the future

approach with @n1k0, @hexid, and @paazmaya...

EDIT (see also discussion at #1342)

@jefleponot
Copy link
Collaborator Author

Another issue for you @istr : casperJS has never used "window.callPhantom" method before this PR.
It could be better to normalize this remote operation.

"window.callPhantom" is similar to the "window.postMessage" function : postMessage(data, targetDomain)

So it could be great to use the same object attributes

The special propertys of a message event are:

data
    The first argument of postMessage
origin
    The source domain
source
    The reference to sending window if it is possible to 
respond by calling event.source.postMessage

chrome extensions has yet normalize communications with the "message passing" :
https://developer.chrome.com/extensions/messaging
Message Passing is really useful to communicate between web page and "background page" (one to one) And also between many pages. It avoid to fall victim to cross-site scripting.

In the modules/casper.js file a senMessage method could be add like the chrome.tabs.sendMessage : sendMessage(integer tabId, any message, object options, function responseCallback)

Thanks for yours advices

@mickaelandrieu
Copy link
Member

@istr sounds OK to me 👍

@eloitay
Copy link

eloitay commented Mar 14, 2016

@jefleponot I tried patching this change into the source code myself and notice that it still produce zero byte files. So I am wondering if the way the script is written need to be changed as well in order for the bug to be fixed.

@jefleponot
Copy link
Collaborator Author

Hi @eloitay
Could you send me you code ? I could help you more

Or you can do a PR with an example.

@@ -410,7 +437,7 @@ Also have a look at `forward()`_.
``base64encode()``
-------------------------------------------------------------------------------

**Signature:** ``base64encode(String url [, String method, Object data])``
**Signature:** ``base64encode(String url [, String method, Object data, Boolean async])``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would give the impression that the third parameter is required when the second is given.
Perhaps (String url [, String method [, Object data, Boolean async ] ] )

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

@BIGjuevos
Copy link
Member

Do we want to keep this issue in the 1.1 release @istr @mickaelandrieu? I vote to move to a new milestone 1.2.

I feel like this would be good for a 1.2 considering our focus on squashing bugs for 1.1. This is something I'd be happy to pick up in the future. Feel free to assign to me.

@mickaelandrieu
Copy link
Member

Humm ok for 1.2, how many issues are blocking the release of 1.1 according to the actual milestone?

@jefleponot
Copy link
Collaborator Author

test ok - PhantomJS 1.9.7 -> 2.1.1
test ok - SlimmerJS 0.8.4 -> 0.9.6

result : 6748 octets
logo

code :

var casper = require("casper").create();

casper.start("http://www.google.fr/", function() {
    this.download("http://www.google.fr/images/srpr/logo3w.png", "logo.png",'GET',{},true);
});
casper.then(function(){
    this.waitForDownload("http://www.google.fr/images/srpr/logo3w.png",function(){
        console.log('download sucess');
    }, function(){
        console.log('download failed');
    });
});
casper.run();

It is fully functional , works in production since January 2016 with phantomJS 2.1.1 because old download method can't be used

@istr istr modified the milestones: 1.2, 1.1 Apr 8, 2016
@jefleponot jefleponot force-pushed the downloadAsync branch 2 times, most recently from 013a1ab to 7a324e8 Compare July 1, 2016 10:46
@jefleponot
Copy link
Collaborator Author

@mickaelandrieu : update done

@mickaelandrieu
Copy link
Member

mickaelandrieu commented Jul 1, 2016

@jefleponot sadly, your last merged pull request have been merged and so on you need to rebase this one 💃

@casperjs/contributors so, are we agree to merge this one? my vote is 👍

@istr
Copy link
Collaborator

istr commented Jul 2, 2016

I would prefer not to break the API in this way:

  • do not introduce boolean parameters
  • especially do not introduce boolean parameters that change the previous "default" behaviour
  • do not make the default behaviour / value dependent on the engine version in use

See https://github.com/casperjs/casperjs/issues/1342#issuecomment-207848750 what I would like to see in this PR instead:

  • mark the current (broken) API functions obsolete and add a "broken" comment to the docs
  • add a warning to those functions that say: "this is broken and will not work; it is obsolete and will be removed"
  • create a new set of functions that implements what this PR achieves

@jefleponot
Copy link
Collaborator Author

@istr,

Thanks for your explanation.

you are right, this PR don't suit for many reasons.
JavaScript programming is now moving towards a purely asynchronous programming.

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

With PhantomJS and SlimerJS, on the opposite, methods are mixed synchronous or asynchronous :

  • open(url, callback) - asynchronous
  • evaluateAsync(function, [delayMillis, arg1, arg2, ...]) - asynchronous
  • ==> page.evaluate(function, arg1, arg2, ...) - synchronous
  • ==> page.render (filename [, {format, quality}]) - synchronous
  • ==> page.renderBase64(format) - synchronous

If you look for an equivalent approach like chrome.tabs, every methods are fully asynchronous :

CasperJS has same trouble as PhantomJS and SlimerJS : mix synchronous and asynchronous fct.
wait(), waitFor(), waitForAlert(), waitForPopup() ... - asynchronous
withFrame(), withPopup() - asynchronous

download() - synchronous
evaluate() - synchronous

The use of Synchronous mode, although it eases writing limits treatments.

@istr, could we propose a new set of asynchronous functions what could lead CasperJS to good javascript practices ?

@mickaelandrieu
Copy link
Member

@jefleponot @istr I agree with Jef, and we need to keep the old api.

Could be better for now to create new functions instead of improve the existing one (and this may be a good start for 2.0 api :) )

@sairoko12
Copy link

Someone what happened with this request?

@kensoh kensoh added the ARCHIVE label Jul 26, 2018
@kensoh
Copy link
Member

kensoh commented Jul 26, 2018

Archiving PR using ARCHIVE label as CasperJS, like PhantomJS, is not actively maintained for now. These PRs are from 1-5 years ago but there just hasn't been maintainers to continue the work.

@kensoh kensoh closed this Jul 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
8 participants