I'm trying to use phantomJS to capture a screenshot of a URL, however when I call phantomJS (from either the command line or web app) it hangs and seesm to never execute the "exit()" call. I can't seem to find any error messages and it remains running until I kill it. This is the JS file that is passed to the phantomjs command:
var page = require('webpage').create();
var system = require('system');
var script_address = '';
var page_to_load = '';
var members_id = '';
var activities_id = '';
var folder_path = '';
if (system.args.length < 5)
{
console.log('Usage: phantom_activity_fax.js script_address page_to_load members_id activities_id folder_path');
console.log('#Args: '+system.args.length);
phantom.exit();
}//END IF SYSTEM.ARGS.LENGTH === 1
//ASSIGN OUR ARGUMENTS RECIEVED
script_address = system.args[0];
page_to_load = system.args[1];
members_id = system.args[2];
activities_id = system.args[3];
folder_path = system.args[4];
console.log(system.args[0]);
console.log(system.args[1]);
console.log(system.args[2]);
console.log(system.args[3]);
console.log(system.args[4]);
//OPEN OUR PAGE WITH THE VALUES PROVIDED
page.open(page_to_load, function () {
console.log("Entering Anonymous Function, Beginning RENDER:\n");
page.render(folder_path+members_id+'_'+activities_id+'.png');
phantom.exit();
});
I see the values pushed to the console, but after that it just hangs :( I've tried the web inspector, but could not understand where to execute the __run() call, and didn't see any change when I added the debugger-autorun=yes to the call :(.
This is the output I get from the command line when it hangs (as root user):
[root#wv-wellvibe2 faxes]# phantomjs /var/www/wv-wellvibe2-test/javascripts/phantom_activity_fax.js https://wv-wellvibe2-test/manual_scripts/phantom_js_test_page.php 397 0 /var/www/wv-wellvibe2-test/uploads/images/faxes/
/var/www/wv-wellvibe2-test/javascripts/phantom_activity_fax.js
https://wv-wellvibe2-test/manual_scripts/phantom_js_test_page.php
397
0
/var/www/wv-wellvibe2-test/uploads/images/faxes/
And this is the output I get when running it as my own user, but I don't see the image file in the designated folder (faxes):
[user#wv-wellvibe2 ~]$ phantomjs /var/www/wv-wellvibe2-test/javascripts/phantom_activity_fax.js https://wv-wellvibe2-test/manual_scripts/phantom_js_test_page.php 397 0 /var/www/wv-wellvibe2-test/uploads/images/faxes/
/var/www/wv-wellvibe2-test/javascripts/phantom_activity_fax.js
https://wv-wellvibe2-test/manual_scripts/phantom_js_test_page.php
397
0
/var/www/wv-wellvibe2-test/uploads/images/faxes/
Entering Anonymous Function, Beginning RENDER:
[user#wv-wellvibe2 ~]$
Unfortunately, as I said, the command completed but did not save a .png in the faxes folder. Here is the permissions for that folder:
[root#wv-wellvibe2 faxes]# ls -la
total 12
drwxr-xr-x 3 root apache 4096 May 16 15:31 .
drwxr-xr-x 5 apache apache 4096 May 16 14:14 ..
drwxr-xr-x 6 apache apache 4096 May 20 15:05 .svn
Please let me know if there is anything else I can provide!
Thank you!
(As requested here is the PHP script that calls the Phantom JS process)
header("Date: " . date('Y-m-d H:i:s'));
//GET THE SMARTY CONFIG
include_once $_SERVER['DOCUMENT_ROOT'] . "/smarty/configs/config.php";
//VARS USED LATER
$process_script = $_SERVER['DOCUMENT_ROOT'] . '/javascripts/phantom_activity_fax.js';
$page_to_load = 'https://' . $_SERVER['HTTP_HOST'] . '/manual_scripts/phantom_js_test_page.php';
$members_id = $_SESSION['members_id'];
$activities_id = 0;
$folder_path = $_SERVER['DOCUMENT_ROOT'] . 'uploads/images/faxes/';
$system_response = '';
$call = "phantomjs --remote-debugger-port=65534 --remote-debugger-autorun=yes " . $process_script . " " . $page_to_load . " " . $members_id . " " . $activities_id . " " . $folder_path;
echo 'CallingSystemWith: ' . $call . '<br />';
try
{
$system_response = system($call);
echo '<br />SystemResponse: ' . $system_response . '<hr />';
} catch (Exception $exc) {
echo $exc->getTraceAsString();
}//END TRY / CATCH
(The page it tells PhantomJS to "scrape" is a simple PHP script that outtputs a print_r() of $_SESSION and $_REQUEST)
If something goes wrong in your script (such as in page.render), phantom.exit() will never be called. That's why phantomJs seems to hang.
Maybe there is an issue in page.render but I don't think so. The most common causes of hangs are unhandled exception.
I will suggest you 4 things to investigate the issue :
add an handler to phantom.onError and/or to page.onError
encapsulate your code in try/catch blocks (such as for page.render)
Once the page is loaded, there is no test on callback status. It's better to check the status
seems to freeze when calling page.render. Have you tried a simpler filename in the current directory ? Maybe the freeze is because of the security or invalid filename (invalid characters ?)
Hope this will help you
Use :
$phantomjs --debug=true rasterize.js http://... test.pdf
In rasterize.js add a timeout on ressource, that was my problem:
page.settings.resourceTimeout = 10000; // Avoid freeze!!!
Related
Because of reasons, I have a situation in which I need to use a .js file to call a .bat file, which calls a .ps1 file. It may sound crazy, but yes, I have to launch the .ps1 file this way.
My problem is that, the .js file is hanging after writing a variable number of errors. The number of errors that causes the script to hang changes between scripts, but seems to be consistent within a script.
I have included sanitized scripts below.
Every time I run this particular combo using cscript (cscript c:\temp\test.js "c:\temp\test3.bat"), the script stops after writing "Checking device 10 of 100." to the log file and does not return me to the prompt. If I run the .bat file from the same command prompt, the script runs as expected. If, on line 41 of the .ps1 script, I change the message type from "Error" to "Verbose" (for example), the script runs fine and completes as expected.
It seems that the .js file does not like something about "Write-Error $Message" from the Out-PsLogging function but:
I cannot tell what it doesn't like
I cannot tell why it stops writing errors after (in this case) 10 errors
I have seen this behavior on Windows 10 and Server 2019 (ps 5.1).
Code:
test.js
var wshShell = new ActiveXObject("WScript.Shell");
var cmdLine = WScript.Arguments(0);
var result = {};
result.stdout = "";
result.stderr = "";
result.exitCode = -1;
if (!wshShell) {
WScript.Echo("Can not run command");
}
var oExec;
try {
oExec = wshShell.Exec(cmdLine);
WScript.Echo("Ran the command - " + cmdLine);
WScript.Echo(oExec.Status);
var line;
WScript.Echo("About to start while loop");
while (oExec.Status != 1) {
WScript.Echo(oExec.Status);
while (!oExec.StdOut.AtEndOfStream) {
WScript.Echo("Inside the second while loop");
line = oExec.StdOut.ReadLine();
result.stdout += line + "\n";
WScript.Echo(line + "\n");
WScript.Echo(oExec.StdOut.AtEndOfStream);
}
while (!oExec.StdErr.AtEndOfStream) {
WScript.Echo("Inside the third while loop");
line = oExec.StdErr.ReadLine();
result.stderr += line + "\n";
WScript.Echo(line + "\n");
WScript.Echo(oExec.StdErr.AtEndOfStream);
}
WScript.Sleep(100);
}
}
catch (e) {
WScript.Echo("Unable to run command - " + cmdLine);
WScript.Echo(e);
}
test3.bat
cmd.exe /C Powershell.exe -Command "&{C:\temp\test3.ps1 -Verbose}"
test3.ps1
Function Out-PsLogging {
[CmdletBinding(DefaultParameterSetName = 'SessionOnly')]
param(
[Parameter(Mandatory, ParameterSetName = 'File')]
[System.IO.FileInfo]$LogPath,
[Parameter(Mandatory)]
[string]$Message,
[Parameter(Mandatory)]
[ValidateSet('Info', 'Warning', 'Error', 'Verbose', 'First')]
[string]$MessageType
)
$logType = "LogFile"
Switch ($logType) {
"LogFile" {
Switch ($MessageType) {
"Info" { [System.IO.File]::AppendAllLines([string]$LogPath, [string[]]$Message); Write-Host $Message }
"Warning" { [System.IO.File]::AppendAllLines([string]$LogPath, [string[]]$Message); Write-Warning $Message }
"Error" { [System.IO.File]::AppendAllLines([string]$LogPath, [string[]]$Message); Write-Error $Message }
"Verbose" { [System.IO.File]::AppendAllLines([string]$LogPath, [string[]]$Message); Write-Verbose $Message -Verbose }
"First" { [System.IO.File]::WriteAllLines($LogPath, $Message); Write-Verbose $Message -Verbose }
}
}
}
}
$a = 0
$array = #(1..100)
$LogPath = 'C:\temp\log3.txt'
$message = ("{0}: Beginning {1}." -f ([datetime]::Now).ToString("yyyy-MM-dd`THH:mm:ss"), $myinvocation.MyCommand)
Out-PsLogging -LogPath $LogPath -MessageType First -Message $message
$itGlueConfigsMatchingPolicy = Foreach ($device in $array) {
$a++
$message = ("{0}: Checking device {1} of {2}." -f ([datetime]::Now).ToString("yyyy-MM-dd`THH:mm:ss"), $a, $array.count)
Out-PsLogging -LogPath $LogPath -MessageType Error -Message $message
}; Remove-Variable a -Force
$message = ("{0}: Completed {1}." -f ([datetime]::Now).ToString("yyyy-MM-dd`THH:mm:ss"), $myinvocation.MyCommand)
Out-PsLogging -LogPath $LogPath -MessageType Verbose -Message $message
Turns out the issue is a bug in wscript: https://groups.google.com/forum/#!topic/microsoft.public.scripting.wsh/kIvQsqxSkSk
PHP creates the text from metadata from image file which stores it in variable of the same name of IMG source.
No Problems
JavaScript displays the gallery to show images, scroll & enlarge.
During enlargement it gives description of image from source attribute but always displays the text with � after every character. But PHP doesn't.
I've tried encoding which you will see from code & & echo header("Content-Type: text/html; charset=ISO-8859-1");
PHP:
$path = "gallery/";
$objs = new RecursiveIteratorIterator(new
RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::SELF_FIRST);
$num = 0;
foreach ($objs as $pic){
$pic = str_replace('gallery/', '', $pic);
if ($pic == '..' or $pic == '.'){
continue;
}
$exif = exif_read_data("$DIR/gallery/$pic", 0, true);
$pic = str_replace('.JPG', '', $pic);
${$pic} = $exif['IFD0']['Comments']; ///// php Variable
echo "<script> var $pic = '".$exif['IFD0']['Comments']."';
var $pic = utf8_encode($pic);</script>";
// JS of variable of same name.
}
Sloppy but Works
JQuery:
$('#mSide').on('click',function(){
var src = $('#mPic').attr('src');
var v = src.replace('/gallery/','');
v = v.replace('.JPG','');
v = unescape(encodeURIComponent(v));
$('#fullPic').show();
$('#fullPic').append('<img class=\"fPic\" src=\"'+src+'\"
height=\"90%\" widdth=\"90%\" style=\"margin-left:0px;\" />');
$('#fullPic').append('<span id=\"picSummary\"
style=\"color:#FFFFFF;\" >testing <textarea > '+ window[v] +'</textarea>
</span>');
$('#fullPic').prepend('<input class=\"closeFullP headr\"
value=\"Close\" READONLY><br class=\"closeFullP\">');
});
Sloppy but Works and window[v] is the call
Should display: this is the new val = NOTICE: This e-mail message may contain legally privileged and/or confidential information. If you are not the intended recipient, you are hereby notified that any dissemination of the contents of this message is strictly prohibited. If you have received this message in error, please immediately notify the sender at ########### and delete all copies of this e-mail message and its attachments.
Not: N�O�T�I�C�E�:� �T�h�i�s� �e�-�m�a�i�l�
�m�e�s�s�a�g�e� �m�a�y� �c�o�n�t�a�i�n�
�l�e�g�a�l�l�y� �p�r�i�v�i�l�e�g�e�d� �a�n�d�/�o�r�
�c�o�n�f�i�d�e�n�t�i�a�l� �i�n�f�o�r�m�a�t�i�o�n�.�
�I�f� �y�o�u� �a�r�e� �n�o�t� �t�h�e�
�i�n�t�e�n�d�e�d� �r�e�c�i�p�i�e�n�t�,...............
Never use utf8_encode() or utf8_decode() they make awful assumptions and happily/silently corrupt your data. Always use a function that allows you to explicitly specify your input and output encodings.
The data you're extracting from EXIF is encoded as UTF16-LE, and your page is... something else. I can't tell what and you should probably figure that out and be consistent.
Suggested reading: UTF-8 all the way through
If your page is encoded as ISO-8859-1:
$proper = mb_convert_encoding($input, 'ISO-8859-1', 'UTF-16-LE');
If your page is encoded as UTF-8:
$proper = mb_convert_encoding($input, 'UTF-8', 'UTF-16-LE');
Ref: https://secure.php.net/manual/en/function.mb-convert-encoding.php
I've been working on a web interface for iPerf and it's going pretty well. My goal is to have the output of the commands be streamed live on the page. It works for iPerf2 commands but when I run iPerf3, it only shows the output once the entire test is complete.
Based on my research I've done on this site and others, I'm thinking it might have something to do with the buffer. I've been messing around with flushing the buffer at different times or setting the 'fread' length to different values but I can't get it to act the same as regular iperf commands. I think this because instead of running the 'popen' on the iperf command itself, I used popen on a python script that would run the iperf command. This still returned the same issue. It only shows the output on the web page once the entire test is complete.
Here is my code:
phpQ.php
<!DOCTYPE html>
<html>
<body>
<div>
Server Domain/IP Address: <input id="address" type="text"><br>
<input id="run" type="button" value="iPerf"><br><br>
</div>
<div id="result"></div>
<script>
function updateText(address) {
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (this.readyState == 3) {
var old_value = document.getElementById("result").innerHTML;
document.getElementById("result").innerHTML = this.responseText;
}
};
if (purpose == 1) {
var url = 'ajaxQ.php?address='+address;
ajax.open('GET', url,true);
ajax.send();
}
}
document.getElementById("run").onclick = function(){
address = document.getElementById("address").value;
purpose = 1;
updateText(address);
}
</script>
</body>
</html>
ajaxQ.php - to see the difference, change "iperf -c" to "iperf3 -c" in the $iperfCmd variable.
<?php
function liveExecuteCommand($cmd,$address)
{
while (# ob_end_flush()); // end all output buffers if any
// tells the user what command is going to run
echo "<pre>Running Command: '".$cmd."'</pre>";
// open the command to run and read output
$proc = popen("$cmd", 'r');
$live_output = "";
$complete_output = "";
while (!feof($proc))
{
# flush();
$live_output = fread($proc,4096);
// adds the live output to the complete output
$complete_output = $complete_output . $live_output;
// prints the live output
echo "<pre>$live_output</pre>";
}
sleep(1);
// close the process
pclose($proc);
echo "<pre>------------------------------------------------------------\nAll Done!</pre>";
}
// this happens if the iPerf button is pressed
if (isset($_GET['address'])) {
$address = $_GET['address'];
$iperfCmd = "iperf -c ".$address." -i 1 -t 5";
liveExecuteCommand($iperfCmd,$address);
}
else{
echo "No post request";
}
?>
FYI, I am running the iperf client on an 'Ubuntu 16.04.2 LTS' CLI server and the iperf server on an 'Ubuntu 16.04 LTS' desktop server.
Thanks for any help!
I have a Phantomjs script that tries to open a url. phantomjs returns this error:
Unable to load resource (request ID:undefinedURL:http://foo.bar/tree/nav_value/27)
Error code: 203. Description: Error downloading http://foo.bar/tree/nav_value/27 - server replied: Not Found
But when I open the url http://foo.bar/tree/nav_value/27 with chrome browser, there's no problem and the page is loaded correctly!
This is the script:
// Read the Phantom webpage '#intro' element text using jQuery and "includeJs"
"use strict";
var page = require('webpage').create();
var system = require('system');
if (system.args.length != 2) {
console.log("please pass 2 argument")
}
var company_id = system.args[1]
console.log("c", company_id)
page.onConsoleMessage = function(msg) {
console.log("message", msg);
};
page.onResourceError = function(resourceError) {
console.log('Unable to load resource (request ID:' + resourceError.id + 'URL:' + resourceError.url + ')');
console.log('Error code: ' + resourceError.errorCode + '. Description: ' + resourceError.errorString);
};
page.onError = function(msg, trace) {
console.log("error", msg)
}
var nav_value;
page.open("http://foo.bar/tree/nav_value/27", 'post', 'username=navid&password=test', function(status) {
if (status === "success") {
page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
page.evaluate(function() {
nav_value = parseInt($("#value").text());
});
phantom.exit(0);
});
} else {
phantom.exit(1);
}
});
EDIT:
Something odd happens. When I run this code with phantomjs on windows on another machine it works. But on Ubuntu it returns the error!
The url that phantomjs is trying to open is on the same server. (Ubuntu)
What is the problem?
Not sure this will help, but I have some ideas that helped me figure out problems with PhantomJS in the past.
First, as you say it works on another machine, you may want to test other versions of PhantomJS, by downloading the executable and specifying the path on your Python script. Version 1.9.8 helped me with bypassing some security restrictions in the past (I also left some settings in case it may interest).
driver = webdriver.PhantomJS(
executable_path='/path/to/the/downloaded/phantomjs19',
# you can specify args, such as:
service_args=[
'--ignore-ssl-errors=true',
'--ssl-protocol=any',
'--web-security=false',
],
# and also other capabilities:
desired_capabilities={
'phantomjs.page.settings.resourceTimeout': '5000',
'phantomjs.page.settings.userAgent': (
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/53 "
"(KHTML, like Gecko) Chrome/15.0.87"
),
},
)
You may also try to see if upgrading Selenium helps.
pip install selenium --upgrade
Another idea that might help to understand what is happening is to try to print a screenshot and log the page source before the error happens. You can do it like:
# Set the window size to something appropriate for your tests.
driver.set_window_size(900, 800)
driver.save_screenshot('screen.png')
# Check if the page source matches your expectations.
with open('temp.html', 'w') as f:
f.write(driver.page_source)
Please, let me know if this helps!
Firstly, I apologize if this issue has been posted before, I couldn't find the answer anywhere.
I'm writing a one page website that uses JavaScript, Ajax and PHP to take key presses and send them out via serial port.
I'm testing it on EasyPHP and WAMP, I'm yet to test on a Linux server.
My problem is that when keys are pressed rapidly I get the error below.
Warning: fopen(com4): failed to open stream: Permission denied in \keypresstest.php on line 7
If I press keys slowly, around 500ms intervals, it all works fine.
Furthermore, following the error above, PHP does not set my $fp variable, so it also returns errors:
Warning: fwrite() expects parameter 1 to be resource, boolean given in \keypresstest.php on line 9
Warning: fclose() expects parameter 1 to be resource, boolean given in \keypresstest.php on line 10
I think that there is slow 'release' of the serial port resource which it's defining as 'Resource id #3' and if I could some how speed this up or spawn another instance when needed i might be able to resolve the issue.
I hope someone reading this might have some advice.
My code is below, I've removed some components to keep this code more concise
HTML File
<script> <!-- call php script here -->
function sendKey(str) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("txtHint").innerHTML = document.getElementById("txtHint").innerHTML + xmlhttp.responseText;
}
}
xmlhttp.open("GET", "keypresstest.php?q=" + str, true);
xmlhttp.send();
}
</script>
<script> // page js key listener script
document.addEventListener('keydown', function(event) { // things happen as keys are pressed
if (!arrayContainsCheck(keysHeld, event.keyCode)) { // check if the key is already being held, this is so keydown events don't continue to propagate whilst a key is held
if(event.keyCode == 38 || event.keyCode == 87) { // up/w keys, send output to php script "f"
sendKey("f");
} keysHeld.push(event.keyCode);
}
});
document.addEventListener('keyup', function(event) {
document.getElementById("lightSwitch").style.backgroundColor = "blue";
if(event.keyCode == 38 || event.keyCode == 87) { // up/w keys, send output to php script "g"
document.getElementById("upArrow").style.border = "1px solid red";
sendKey("g");
}
keyRelease(keysHeld, event.keyCode);
});
</script>
PHP File
<?php
$q = $_REQUEST["q"]; // get the q parameter from URL
// Output q parameter to com4 serial port
echo "q is $q <br />";
echo "defining fp... <br />";
$fp = fopen("com4", "w");
echo "fp defined as " . $fp . " .<br />";
fwrite($fp, $q);
fclose($fp);
?>