rialto-php / puphpeteer

A Puppeteer bridge for PHP, supporting the entire API.
MIT License
1.34k stars 208 forks source link

catch ajax response with page.on("response").. #63

Open sanhar opened 5 years ago

sanhar commented 5 years ago

Hi.

I need catch ajax response . I know I can use this following in Puppeteer .

page.on("response", async response => { });

How can I apply this event listener for php ?

toix commented 5 years ago

There is a similar issue: https://github.com/nesk/puphpeteer/issues/33 I think the issue is in rialto: https://github.com/nesk/rialto/issues/19

sngrl commented 3 years ago

Hello, so how I can catch ajax requests call & process responses?

mb0000 commented 3 years ago

I'm not suggesting this is a good solution, but it works for me. 1) Create a logger to pass in to the Puppereer constructor (these are Rialto options). The log method of the logger looks for a particular pattern in the context parameter of the log data (to identify CDP Event messages). For matching patterns and previously set up Event callbacks, the logger then invokes the callback within your code. (see extracts below) 2) Use $page->target()->createCDPSession() to create a CDP session 3) Use the callbacks to capture CDP events as you need them

[Some of the] Logger methods (refer to PSR Logging documentation / examples for the fuller picture - that's all I did):


    /**
     * @param   object      $cdpSession
     * @param   string      $event
     * @param   callable    $callback
     *
     * @return  bool
     */
    public function onEvent( $cdpSession, $event, $callback ) {

        $r = is_callable( $callback );
        if ($r) {

            $this->eventCallbacks[ $event ] = $callback;
            $js = 'console.log( JSON.stringify({"event":"'. $event .'","arguments": arguments}) );';

            $jsFunction = JsFunction::createWithBody( $js );

            $cdpSession->on( $event, $jsFunction );

        } elseif (($callback === null)
                   && array_key_exists( $event, $this->eventCallbacks ) ) {

            unset( $this->eventCallbacks[ $event ] );
            $r = true;
        }
        return $r;
    }

    // -----------------------------------------------------------------------------------------------------------------
    /**
     * {@inheritDoc}
     *
     * @param mixed $level
     * @param string $message
     */
    public function log($level, $message, array $context = []): void {

        $message = $this->interpolate($message, $context);
        $addToLog = true;

        if ((count( $context ) == 3)
            && array_key_exists( 'pid', $context )
            && array_key_exists( 'port', $context )
            && array_key_exists( 'log', $context )
        ) {

            $logEntry = $context['log'];
            $jsonObj = @json_decode( $logEntry, $this->returnDataAsArray );
            if ( ($jsonObj !== null)
                 && ( ( ! $this->returnDataAsArray
                        && is_object( $jsonObj )
                        && property_exists( $jsonObj, 'event')
                        && property_exists( $jsonObj, 'arguments' )
                        && array_key_exists( $jsonObj->event, $this->eventCallbacks ) )
                      ||
                      ( $this->returnDataAsArray
                        && is_array( $jsonObj )
                        && array_key_exists( 'event', $jsonObj )
                        && array_key_exists( 'arguments', $jsonObj )
                        && array_key_exists( $jsonObj['event'], $this->eventCallbacks ) )
                )
            ) {

                $addToLog = false;
                if ($this->returnDataAsArray) {

                    $this->eventCallbacks[ $jsonObj['event'] ]( $jsonObj['event'], $jsonObj['arguments'] );

                } else {

                    $this->eventCallbacks[ $jsonObj->event ]( $jsonObj->event, $jsonObj->arguments );
                }
            }
        }
        if ($addToLog) $this->logger::addToLog(
            $this->fn,
            date('Ymd-His')
            . $this->sepChar .microtime( true )
            . $this->sepChar .__FILE__ . $this->sepChar .  __LINE__
            . $this->sepChar .'['. $level .']'
            //. $this->sepChar .get_called_class()
            .' '
            . $message
            . print_r( $context, true )
            .PHP_EOL
        );
    }

Example "on" event set up within your Puppeteer interacting classes:

            $this->logger->onEvent(
                $this->cdpSession,
                self::$eventMethodValuePageLoadEventFired,
                array( $this, 'commentEventHandler')
            );

Example event callback method:

    /**
     * @param   string      $eventName
     * @param   array       $data
     */
    public function commentEventHandler( $eventName, $data ) {

        if (is_array( $data ) || is_object( $data ) ) {

            foreach( $data as $key => $eventData ) {

                switch( $eventName ) {

                    case wsc_cdp::$eventMethodValuePageLoadEventFired:
                        // Now inspect $eventData array for the elements of interest - see the CDP documentation
                        break;

                    default:
                }
            }
        }
    }