Web Services Fundamentals: Difference between revisions
Line 89: | Line 89: | ||
* When we run in a local browser, the origin of the app is our local machine. | * When we run in a local browser, the origin of the app is our local machine. | ||
* So the browser protests when we try to run a PHP script on another machine. | * So the browser protests when we try to run a PHP script on another machine. | ||
=== Using POST to Send more Data to the Server and save it === | |||
Let's extend what we are doing a bit and talk about using the POST method. | |||
We discussed the simplest [[Ajax]] call, which sends data to the server by adding it to the end of the URL, a method called, rather misleadingly, GET. But what if we want to send more data? GET has a limit, some say, of around 2000 characters. For more than that, we'll use the also badly named POST method. POST has an upload limit on most servers of 8 megabytes. If you need more, server settings can be adjusted. | |||
Let's look at some code. You'll see it looks very much like our last post: | |||
<pre> | |||
Function btnAjax_onclick() | |||
req=Ajax("ajaxPost.php","POST",txtSend.value) | |||
If req.status=200 Then 'success | |||
htmResponse.innerHTML=req.responseText | |||
Else 'failure | |||
htmResponse.innerHTML="Error: " & req.err | |||
End If | |||
End Function | |||
</pre> | |||
The difference is a couple of extra parameters. We add "POST" and the data we want to send as a separate parameter. Before we talk about what is going to happen at the server end, let's see what the app looks like: | |||
[[File:Ajaxpost.png]]<br /> | |||
OK, here is the PHP code on the server which we are calling: | |||
<pre> | |||
<?php | |||
// uncomment the next line to see runtime error messages from this script | |||
// ini_set('display_errors','1'); | |||
// Get the data from the client. | |||
$myText = file_get_contents('php://input'); | |||
// Send back the text, reversed | |||
echo "Data received from Device (reversed):<br>" . strrev($myText); | |||
//write the data out to a file on the server | |||
//make sure permissions are all OK! | |||
$myFile = "AjaxPost/ajaxPost.txt"; | |||
echo "<p>Writing data to " . getcwd() . $myFile; | |||
$f = fopen($myFile, 'w') or die("can't open file"); | |||
fwrite($f, $myText); | |||
fclose($f); | |||
?> | |||
</pre> | |||
The file_get_contents('php://input') call gets the data, exactly as it was sent. We'll do two things with it: echo it back reversed and we will write it to a file on the server. The first part is easy: anything in an echo statement is sent back to our app: | |||
<pre> | |||
echo "Data received from Device (reversed):" . strrev($myText); | |||
</pre> | |||
The second part involves a bit more PHP, but is straightforward. It writes the data which was received to a file. | |||
<pre> | |||
$myFile = "AjaxPost/ajaxPost.txt"; | |||
echo "<p>Writing data to " . getcwd() . $myFile; | |||
$f = fopen($myFile, 'w') or die("can't open file"); | |||
fwrite($f, $myText); | |||
fclose($f); | |||
</pre> | |||
What would you use this feature for? | |||
* Upload a JSON copy of your database. | |||
* Upload some pictures in Base64 format. | |||
* Create a .htm file which can be accessed as a web page. | |||
* Lots more ideas! | |||
A tip on debugging PHP scripts Since PHP scripts run on the server and not on your screen, you don't get to see the error messages. This can make debugging difficult. If you put this statement at the top of your PHP script, the error messages will be echoed to your app: | |||
<pre> | |||
ini_set('display_errors','1'); | |||
</pre> | |||
The error messages come back as HTML formatted text. The best way to look at them is to assign them to the innerText property of an HTMLview control. |
Revision as of 16:30, 10 December 2013
Introduction
- Web Services are resources which are accessed over the web
- AppStudio Apps can access Web Services
- The information that is pulled from the web can make interesting apps
- Data can be pulled from your own server or someone else's.
- Mashups are apps which pull information from more than one source
Same Origin Policy and CORS
Same Origin Policy (SOP): The policy permits scripts running on pages originating from the same site – a combination of scheme, hostname, and port number – to access each other's DOM with no specific restrictions, but prevents access to DOM on different sites.
Cross Origin Resource Sharing (CORS): is a mechanism that allows scripts on a web page to make AJAX requests to another domain, not the domain the script originated from. Such "cross-domain" requests would otherwise be forbidden by web browsers, per the Same Origin Policy.
- Suppose we create an AppStudio app.
- It gets saved on our server (nsbapp.com), together with all the files it needs to run.
- When someone runs it, they enter http://www.nsbapp.com/HelloWorld into their browser.
- The app is then loaded from the website and stored on the device.
- Since the app is loaded from nsbapp.com, SOP allows it to access resources on nsbapp.com: HTML, JavaScript, CSS files, images, etc.
- However, it would not be allowed full use of resources on another site, such as nsbasic.com.
- CORS is a way of allowing apps running from another server to access specific resources on the server.
AJAX
AJAX: stands for Asynchronous JavaScript and XML. It is a group of interrelated web development techniques used on the client-side to create asynchronous web applications.
- It has evolved since it was originally named.
- Now, it does not necessary involve asynchronous, JavaScript or XML!
- The AppStudio AJAX statement allows an app to request information from a web service.
- It is based on the XMLHttpPost function in JavaScript.
A Simple Exchange of Data with the server
Let's look at some code. We will have our AppStudio app send the server a string, which the server will return reversed. Here is what the app looks like:
The only code in this app is the "Reverse" button. The Ajax function sends the contents of the top TextArea to a PHP script that is running on the server. If it returns successfully, we display what came back. Otherwise, we show the error:
Dim req Function btnAjax_onclick() req=Ajax("ajax.php/?myText=" & txtSend.value) If req.status=200 Then 'success txtResponse.value=req.responseText Else 'failure txtResponse.value="Error: " & req.err.message End If End Function
The PHP script is even easier. It gets the input that is named myText, reverses it, and uses the echo statement to send it back.
<?php // Get the data from the client. $myText = $_GET['myText']; // Send back the text, reversed echo "Data received from Device (reversed): " . strrev($myText); ?>
Here is the result:
- The php script needs to be on the same folder on the server as the AppStudio app.
- It can be uploaded with the app.
- This is equivalent to entering the following URL into a browser:
https://www.nsbasic.com/i/Ajax/ajax.php/?myText=%22NSB/AppStudio%20makes%20Ajax%20easy!%22
Cross Origin Attacks!
What happens if we run this same example in our local browser, by just choosing Start in Desktop Browser under the Run menu?
- We get a cross origin request error.
- The traceback shows it is caused by our Ajax call.
- When we run in a local browser, the origin of the app is our local machine.
- So the browser protests when we try to run a PHP script on another machine.
Using POST to Send more Data to the Server and save it
Let's extend what we are doing a bit and talk about using the POST method.
We discussed the simplest Ajax call, which sends data to the server by adding it to the end of the URL, a method called, rather misleadingly, GET. But what if we want to send more data? GET has a limit, some say, of around 2000 characters. For more than that, we'll use the also badly named POST method. POST has an upload limit on most servers of 8 megabytes. If you need more, server settings can be adjusted.
Let's look at some code. You'll see it looks very much like our last post:
Function btnAjax_onclick() req=Ajax("ajaxPost.php","POST",txtSend.value) If req.status=200 Then 'success htmResponse.innerHTML=req.responseText Else 'failure htmResponse.innerHTML="Error: " & req.err End If End Function
The difference is a couple of extra parameters. We add "POST" and the data we want to send as a separate parameter. Before we talk about what is going to happen at the server end, let's see what the app looks like:
OK, here is the PHP code on the server which we are calling:
<?php // uncomment the next line to see runtime error messages from this script // ini_set('display_errors','1'); // Get the data from the client. $myText = file_get_contents('php://input'); // Send back the text, reversed echo "Data received from Device (reversed):<br>" . strrev($myText); //write the data out to a file on the server //make sure permissions are all OK! $myFile = "AjaxPost/ajaxPost.txt"; echo "<p>Writing data to " . getcwd() . $myFile; $f = fopen($myFile, 'w') or die("can't open file"); fwrite($f, $myText); fclose($f); ?>
The file_get_contents('php://input') call gets the data, exactly as it was sent. We'll do two things with it: echo it back reversed and we will write it to a file on the server. The first part is easy: anything in an echo statement is sent back to our app:
echo "Data received from Device (reversed):" . strrev($myText);
The second part involves a bit more PHP, but is straightforward. It writes the data which was received to a file.
$myFile = "AjaxPost/ajaxPost.txt"; echo "<p>Writing data to " . getcwd() . $myFile; $f = fopen($myFile, 'w') or die("can't open file"); fwrite($f, $myText); fclose($f);
What would you use this feature for?
- Upload a JSON copy of your database.
- Upload some pictures in Base64 format.
- Create a .htm file which can be accessed as a web page.
- Lots more ideas!
A tip on debugging PHP scripts Since PHP scripts run on the server and not on your screen, you don't get to see the error messages. This can make debugging difficult. If you put this statement at the top of your PHP script, the error messages will be echoed to your app:
ini_set('display_errors','1');
The error messages come back as HTML formatted text. The best way to look at them is to assign them to the innerText property of an HTMLview control.