This should be a rather straight forward widget with the usual HTML js/div plugin code, but the issue here is that it won't display the echoed PHP code (output would be plain html on callback from the Python file in /cgi-bin/) within Chrome (the browser I'm testing on). When I run the python code below from the BASH shell it displays the echoed PHP code as plain HTML, but it is not displaying anything when I run the Plugin/HTML code below from within Chrome.
cgi.force_redirect = 0 is set within php.ini, so that shouldn't be the issue. Chrome previously threw an error for the PHP code callback due to cgi-bin / php security, but it isn't throwing that error any more with that set in php.ini.
No errors are showing up in Chrome when I run it now, but it just isn't displaying any of the HTML code that should be coming from the PHP echoed code (that should be displayed from the Python callback). There aren't any callback issues as it displays the JSONP when its set to display just a plain string through Python (non-PHP output). So, it's confirmed that it is working to display data across domains.
I don't know Python very well at all, so that could be the issue here. It's a perplexing issue for me and I put in few days trying to figure this all out before coming here to the experts!
Here is the Plugin/HTML code (included on a third party domain (cross domain), not example.com):
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="https://example.com/widget/widget.js" type="text/javascript"></script>
<div id="widget"></div>
</body>
</html>
Here is the JavaScript Code (widget.js):
(function() {
// Localize jQuery variable
var jQuery;
/******** Load jQuery if not present *********/
if (window.jQuery === undefined) {
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src",
"https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function () { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else {
script_tag.onload = scriptLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
main();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function($) {
/******* Load CSS *******/
var css_link = $("<link>", {
rel: "stylesheet",
type: "text/css",
href: "widget-styles.css"
});
// css_link.appendTo('head');
//alert(element);
/******* Load HTML *******/
var jsonp_url = "https://example.com/cgi-bin/widget-python.py?callback=?";
$.getJSON(jsonp_url, function(data) {
$('#widget').html("This data comes from another server: " + data.html);
});
});
}
})(); // We call our anonymous function immediately
Here is the Python code included in /cgi-bin/ and called from widget.js (widget-python.py):
#!/usr/bin/python
import cgi
import subprocess
params = cgi.FieldStorage()
print "Content-Type: text/javascript\n"
proc = subprocess.Popen("php <pathtophpfile>.php", shell=True, stdout=subprocess.PIPE)
result = proc.stdout.read()
jsonp = "%s ( {'html': " + result + " } )"
#jsonp = "%s ( {'html': 'printastring' } )" THIS WORKS and prints into Chrome when its commented out, but its just a string, and what I need is the PHP output from the result variable above.
#print result This prints the php code out perfectly into the command line when I run execute the python script from within /cgi-bin
print jsonp % params['callback'].value
AS FOR THE PHP CODE (pathtophpfile.php) that is supposed to be echoed out into Chrome, its output is pure HTML div to div and it is displaying in the terminal when run, so Python is finding and running the PHP file.. Thank you for your help, and I hope this is enough information, I'll be adding to it if it is not.
Related
Is there a way I can run a php function through a JS function?
something like this:
<script type="text/javascript">
function test(){
document.getElementById("php_code").innerHTML="<?php
query("hello"); ?>";
}
</script>
<a href="#" style="display:block; color:#000033; font-family:Tahoma; font-size:12px;"
onclick="test(); return false;"> test </a>
<span id="php_code"> </span>
I basically want to run the php function query("hello"), when I click on the href called "Test" which would call the php function.
This is, in essence, what AJAX is for. Your page loads, and you add an event to an element. When the user causes the event to be triggered, say by clicking something, your Javascript uses the XMLHttpRequest object to send a request to a server.
After the server responds (presumably with output), another Javascript function/event gives you a place to work with that output, including simply sticking it into the page like any other piece of HTML.
You can do it "by hand" with plain Javascript , or you can use jQuery. Depending on the size of your project and particular situation, it may be more simple to just use plain Javascript .
Plain Javascript
In this very basic example, we send a request to myAjax.php when the user clicks a link. The server will generate some content, in this case "hello world!". We will put into the HTML element with the id output.
The javascript
// handles the click event for link 1, sends the query
function getOutput() {
getRequest(
'myAjax.php', // URL for the PHP file
drawOutput, // handle successful request
drawError // handle error
);
return false;
}
// handles drawing an error message
function drawError() {
var container = document.getElementById('output');
container.innerHTML = 'Bummer: there was an error!';
}
// handles the response, adds the html
function drawOutput(responseText) {
var container = document.getElementById('output');
container.innerHTML = responseText;
}
// helper function for cross-browser request object
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req.readyState == 4) {
return req.status === 200 ?
success(req.responseText) : error(req.status);
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
The HTML
test
<div id="output">waiting for action</div>
The PHP
// file myAjax.php
<?php
echo 'hello world!';
?>
Try it out: http://jsfiddle.net/GRMule/m8CTk/
With a javascript library (jQuery et al)
Arguably, that is a lot of Javascript code. You can shorten that up by tightening the blocks or using more terse logic operators, of course, but there's still a lot going on there. If you plan on doing a lot of this type of thing on your project, you might be better off with a javascript library.
Using the same HTML and PHP from above, this is your entire script (with jQuery included on the page). I've tightened up the code a little to be more consistent with jQuery's general style, but you get the idea:
// handles the click event, sends the query
function getOutput() {
$.ajax({
url:'myAjax.php',
complete: function (response) {
$('#output').html(response.responseText);
},
error: function () {
$('#output').html('Bummer: there was an error!');
}
});
return false;
}
Try it out: http://jsfiddle.net/GRMule/WQXXT/
Don't rush out for jQuery just yet: adding any library is still adding hundreds or thousands of lines of code to your project just as surely as if you had written them. Inside the jQuery library file, you'll find similar code to that in the first example, plus a whole lot more. That may be a good thing, it may not. Plan, and consider your project's current size and future possibility for expansion and the target environment or platform.
If this is all you need to do, write the plain javascript once and you're done.
Documentation
AJAX on MDN - https://developer.mozilla.org/en/ajax
XMLHttpRequest on MDN - https://developer.mozilla.org/en/XMLHttpRequest
XMLHttpRequest on MSDN - http://msdn.microsoft.com/en-us/library/ie/ms535874%28v=vs.85%29.aspx
jQuery - http://jquery.com/download/
jQuery.ajax - http://api.jquery.com/jQuery.ajax/
PHP is evaluated at the server; javascript is evaluated at the client/browser, thus you can't call a PHP function from javascript directly. But you can issue an HTTP request to the server that will activate a PHP function, with AJAX.
The only way to execute PHP from JS is AJAX.
You can send data to server (for eg, GET /ajax.php?do=someFunction)
then in ajax.php you write:
function someFunction() {
echo 'Answer';
}
if ($_GET['do'] === "someFunction") {
someFunction();
}
and then, catch the answer with JS (i'm using jQuery for making AJAX requests)
Probably you'll need some format of answer. See JSON or XML, but JSON is easy to use with JavaScript. In PHP you can use function json_encode($array); which gets array as argument.
I recently published a jQuery plugin which allows you to make PHP function calls in various ways: https://github.com/Xaxis/jquery.php
Simple example usage:
// Both .end() and .data() return data to variables
var strLenA = P.strlen('some string').end();
var strLenB = P.strlen('another string').end();
var totalStrLen = strLenA + strLenB;
console.log( totalStrLen ); // 25
// .data Returns data in an array
var data1 = P.crypt("Some Crypt String").data();
console.log( data1 ); // ["$1$Tk1b01rk$shTKSqDslatUSRV3WdlnI/"]
I have a way to make a Javascript call to a PHP function written on the page (client-side script). The PHP part 'to be executed' only occurs on the server-side on load or refreshing'. You avoid 'some' server-side resources. So, manipulating the DOM:
<?PHP
echo "You have executed the PHP function 'after loading o refreshing the page<br>";
echo "<i><br>The server programmatically, after accessing the command line resources on the server-side, copied the 'Old Content' from the 'text.txt' file and then changed 'Old Content' to 'New Content'. Finally sent the data to the browser.<br><br>But If you execute the PHP function n times your page always displays 'Old Content' n times, even though the file content is always 'New Content', which is demonstrated (proof 1) by running the 'cat texto.txt' command in your shell. Displaying this text on the client side proves (proof 2) that the browser executed the PHP function 'overflying' the PHP server-side instructions, and this is because the browser engine has restricted, unobtrusively, the execution of scripts on the client-side command line.<br><br>So, the server responds only by loading or refreshing the page, and after an Ajax call function or a PHP call via an HTML form. The rest happens on the client-side, presumably through some form of 'RAM-caching</i>'.<br><br>";
function myPhp(){
echo"The page says: Hello world!<br>";
echo "The page says that the Server '<b>said</b>': <br>1. ";
echo exec('echo $(cat texto.txt);echo "Hello world! (New content)" > texto.txt');echo "<br>";
echo "2. I have changed 'Old content' to '";
echo exec('echo $(cat texto.txt)');echo ".<br><br>";
echo "Proofs 1 and 2 say that if you want to make a new request to the server, you can do: 1. reload the page, 2. refresh the page, 3. make a call through an HTML form and PHP code, or 4. do a call through Ajax.<br><br>";
}
?>
<div id="mainx"></div>
<script>
function callPhp(){
var tagDiv1 = document.createElement("div");
tagDiv1.id = 'contentx';
tagDiv1.innerHTML = "<?php myPhp(); ?>";
document.getElementById("mainx").appendChild(tagDiv1);
}
</script>
<input type="button" value="CallPHP" onclick="callPhp()">
Note: The texto.txt file has the content 'Hello world! (Old content).
The 'fact' is that whenever I click the 'CallPhp' button I get the message 'Hello world!' printed on my page. Therefore, a server-side script is not always required to execute a PHP function via Javascript.
But the execution of the bash commands only happens while the page is loading or refreshing, never because of that kind of Javascript apparent-call raised before. Once the page is loaded, the execution of bash scripts requires a true-call (PHP, Ajax) to a server-side PHP resource.
So, If you don't want the user to know what commands are running on the server:
You 'should' use the execution of the commands indirectly through a PHP script on the server-side (PHP-form, or Ajax on the client-side).
Otherwise:
If the output of commands on the server-side is not delayed:
You 'can' use the execution of the commands directly from the page (less 'cognitive' resources—less PHP and more Bash—and less code, less time, usually easier, and more comfortable if you know the bash language).
Otherwise:
You 'must' use Ajax.
I'm using phantomjs to load a local html, which is loading a local js file, so the paths are like this:
/Users/me/html/page.html
/Users/me/html/page.js
and page.html includes the page.js file, and I can verify that by loading file:///Users/me/html/page.html and see the console.loging in the console for that page.
Now this js file is also merely adding a attribute to the body for testing this issue, which works normally. When I load this html file with PhantomJS however the js file does not change the DOM (ie does not add the attribute to the body).
The js file is loaded last on the html file, so it is at the bottom of the page:
<html>
<head></head>
<body>
<script src="page.js"></script>
</body>
</html>
Again loading this page normally it works, but with a phantom.js script it does not:
var page = require("webpage").create();
var system = require("system");
var args = system.args;
var pageURL = args[1];
page.open(pageURL, function(status) {
if (status !== 'success')
{
console.log(status);
}
else
{
var result = page.evaluate(function()
{
return document.body.getAttribute("data-changed") || "not found";
});
console.log(result);
}
});
the page.js looks like this:
document.body.setAttribute("data-changed", "true");
console.log("changed the page with js!")
So, is PhantomJS supposed to run js from the page being opened? or not? and if it is then what am I doing wrong here?
PhantomJS pages are not directly aware of the filesystem, and the page.js script is practically invisible to your page even though they are in the same directory. Instead of including the script directly in your HTML, you can use Phantom's injectJs to dynamically inject the script once the page is created, and before you evaluate it. injectJs will accept an absolute local path to the script, a path relative to the Phantom script itself, or a remote script, but not one that is relative to the page.
Modify your page.open callback like so:
page.open(pageURL, function(status) {
...
else {
// try to inject page.js
if ( page.injectJs('/Users/me/html/page.js') ) {
// page.js was injected, so evaluate:
var result = page.evaluate(function() {
return document.body.getAttribute("data-changed") || "not found";
});
console.log(result);
}
}
});
Hello,
I am trying to test error supression on Sharepoint but I am having some trouble.
This is my process:
On a relatively plain website (all it contains is a colored-in div), I added this script:
<script>
var x[] = 0;
var err = 10/x;
alert(err);
</script>
When setting my Outlook homepage to this site, I see this error:
I also have the following script, which suppresses this message (when adding this to my code, the error message doesn't appear):
<script type="text/javascript">
window.onerror = function(message, url, lineNumber) {
// code to execute on an error
return true; // prevents browser error messages
};
</script>
I want to test this script out on my Sharepoint site, but when I embed the above, error-inducing code onto my Sharepoint homepage and open the page in Outlook, I am not seeing any error messages.
I added the code in the following ways:
1 - Page > Edit > Edit Source > Added the code to the top
2 - Page > Edit > Embed Code > Added the code to various areas of the page
Neither of these methods worked, and the first one actually produced a message telling me that I should use the embed function, which also doesn't seem to work!
I need to generate this error from the Sharepoint page so that I can check **whether the error-suppressing script actually does what it's supposed to. Can **anyone think of what may be going wrong here?
Any help is much appreciated!
This is apparently a known issue in Sharepoint, and can be resolved by using the following function:
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function(){
//your code goes here...
});
For the purposes of the above test, I was able to generate an error with the following:
<script language='javascript'>
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function(){
var x[] = 0;
var err = 10/x;
alert(err);
});
</script>
And adding the below suppressed the errors:
<script language='javascript'>
window.onerror = function(message, url, lineNumber) {
return true;
};
</script>
Note that this only worked for me after adding the 2 bits of code in their own, seperate <script> tags. I also had to add language='javascript' to the tags before it would work.
I added the code by embedding some new code, and adding both of the script tags to that web part. Because I was able to produce the error message, I was also able to prove that the error-suppression method worked.
New Restful API's like Google, OpenStreetview use a simple call back mechanism.
Basically you call the API, adding a parameter &callback=my function.
When executing a call to this API, as a result my function is called passing a JSON dataset.
I am trying to create the same mechanisme for a API I am building for my personal use.
As far as I understood my API needs to return a javascript, that calls the function that is passed in a script.
For a test I created this:
function apiCall(URL,values, keyPair,cBackPair) {
// URL specifics URL to call
// keyPair: <keyname>=<key>; leave black if unneeded
// cBacPair: <callBackParametername>=<functionname>
// called is: URL?values&keypair&cBackPair
var request = (keyPair)?'&'+keyPair:'';
request = URL + '?'+ encodeURI(values) + request + '&' + cBackPair;
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", request);
document.body.appendChild(script);
}
function callAPI() {
apiCall('http://xllent.nl/map/ajax/answer.php','q=one','','s=doit');
}
function doit(result) {
alert(result);
}
To test I call callAPI onload.
The script answer.php is very basic:
<?$s = $_GET['s'];
?>
<script type="text/javascript">
doit('jeroen');
</script>
Later the script would use $s to call the right script, and of course supply user data.
For now I am just trying to get the script doit('jeroen'); to be run. But nothing happens.
Typing javascript:doit('jeroen'); in the browser window gives the result I would expect.
Any suggestions?
Don't surround your javascript with <script> tags. You are not generating a HTML file with a javascript body.. You should think of this as if you're generating a javascript file on fly.
Javascript files also don't start and end with <script>
I have a series of large html pages in development, each uses a common structure: header / content / sidebar.
Header and sidebar sections have code common to all pages. Only content changes.
During the development phase, I want to be able to make changes to the header and sidebar once and see the results replicated on all pages without having to edit each page separately.
I've done a bit of googling, and the simplest solution seems to be to create 2 separate text files with the code for the header and sidebar sections, and then inject this at the appropriate points in the HTML pages I'm editing.
I know this is not recommended for a live project, as it would dramatically increase the load times, but for dev work it would save me a lot of time.
Would you agree? If so, anybody have any idea what the simplest way to do this is?
Thanks
You would be better to do this with some sort of server-side technology, like PHP. This would make the impact on loading times negligible as the pages would be concatenated before they were sent to the browser.
You would accomplish it by doing something like this:
<?php require('header.php'); ?>
<!-- Main content goes here -->
<?php require('sidebar.php'); ?>
And then have the files header.php and sidebar.php in the same directory as the main files.
Use some sort of serverside templating languate that would allow for you to include files within each other.
If, despite the other answers, you insist on doing this from JavaScript, the following is a module I use :
(function xload (slctr) { //================================================== xload ===
function xloader (src, dst) {
if (arguments.length == 1) {
dst = src;
src = dst.getAttribute ('data-source') || '';
}
var req;
try {
src = src.match (/^([^]*?)(!)?(?:\[\[([^]*?)\]\])?$/);
(req = new XMLHttpRequest ()).open ('GET', src[1], !src[2]);
req.onreadystatechange = function (ev) {
if (this.readyState === 4) {
if (typeof dst == 'function')
dst (req);
else {
dst[dst.tagName == 'TEXTAREA' ? 'value' : 'innerHTML'] = this.responseText;
[].forEach.call (dst.getElementsByTagName ('SCRIPT'), function (s, i) {
var script = document.createElement ('script');
script.innerHTML = s.parentNode.removeChild (s).innerHTML;
document.body.appendChild (script);
})
}
}
};
src[3] && req.overrideMimeType &&
req.overrideMimeType (src[3]);
req.send (null);
} catch (err) { console.log ('xloader error : ', err); }
}
[].forEach.call (document.querySelectorAll (slctr), function (el) { xloader (el); });
}) ('[data-source]'); //------------------------------------------------------ xload ---
Any element, a div for example with a data-source attribute is processed. The data-source specifies the url of the file to be included. When he Ajax request completes, the entire contents of the div are replaced with the text fetched. The data-sourc url may optionally be followed by a ! indicating synchronous load and then by a Mime type enclosed in [[ and ]]
Any scripts in the loaded text are extracted and injected into the document body.
Error conditions are reported on the console.
The module is entirely standalone and processes all elements containing the data-source attribute. It should, of course be loaded after the HTML text of the page.