Orphus system
Russian version
Add to Del.icio.us
English version
Digg It!

 dkLab | Constructor | JsHttpRequest 5: cross-browser AJAX + file uploading 

Site map :: Project «Orphus» :: Constructor


Complete documentation
Protocol specifications

Discuss article in the forum
Download source archive
View online demos
View SVN repository
On the page:
What is AJAX, backend and frontend?
What does JsHttpRequest library offer?
JsHttpRequest usage example
     FRONTEND (md5_frontend.htm)
     BACKEND (md5_backend.php)
Work together with the Prototype library
Conclusion

2006-07-29
Download the library and samples

You could also read the complete library documentation.

This article describes JsHttpRequest - an easy-to-use cross-browser AJAX library with AJAX file uploading support and many other features. JsHttpRequest first appeared as cross-browser analogue of XMLHttpRequest, and then became a very useful instrument to create dynamic web pages. It uses JavaScript (ActiveX, DOM, XMLHttpRequest if available) in frontend and PHP in backend.

Here is a short list of library's most interesting features and benefits.

Note that this article is a short turorial only. If you want more information, please view the following documents:

What is AJAX, backend and frontend?

AJAX (Asynchronous Javascript And XML), "Web 2.0" are technologies which assume more full usage of modern browsers' features (e.g. XMLHttpRequest and DOM). JsHttpRequest AJAX library allows, for example, making sub-queries to a web-server without page reload. You can request anything you want from a server and show it immediately on a dedicated page plock.

A good example of AJAX technology is Google Suggest (http://www.google.com/webhp?complete=1&hl=en):

The example of Google suggestions
Fig 1. Google Suggest. You type request and you get list of results immediately, without page reload.

Every AJAX web page consists of two parts: frontend and backend. In frontend you make queries to web pages and in backend you answer to a query.

The client's browser sends request to server, and gets an answer
Fig 2. Client-server structure of AJAX requests

For dummies 

Frontend is always run in a browser.
Backend is always run on your server.

In frontend we usually write the JavaScript code which passes data to a server, something like that: -

Listing 1: send a query copy code to clipboard
// Send a query.
JsHttpRequest.query(
  "/ajax/suggester",              // backend address
  { query: search_string.value }, // parameters
  function(result, errors) {
     // This function will be called when result is ready.
     // Suggest the most popular word as query.
     autocomplete_query(result["first"]["name"]);
     // Draw "suggestions" to query.
     show_suggestions (result);
  }
);

In backend we can use a PHP code to create an answer for the request. We will write something like the following:

Listing 2: proces a request copy code to clipboard
// Some functions that work with a database.
include "suggestions.lib.php";
// Get the query result.
$query = $_REQUEST["query"];
$result = get_suggestions($query);
// Give a name to the first element of result.
$result["first"] = $result[0];
$GLOBALS['_RESULT'] = $result; // $_RESULT will be passed to frontend

As you can see, there is nothing special in our code. The only thing is that we do not have query() method, and nothing sends the result back. But we do not need to write any more code ourselves, because JsHttpRequest comes out to the stage.

What does JsHttpRequest library offer?

JsHttpRequest AJAX library offers a very useful interface for writing both frontend and backend. You can see how it works just here, if you type something (e.g. "test") in the next field and wait 2 seconds or press Enter for immediate answer:

If you want to make a sub-query to server and you use JsHttpRequest, you will just need to call JsHttpRequest.query() method:

Listing 3: common library call copy code to clipboard
// Code for AJAX FRONTEND.
JsHttpRequest.query(
  address,                     // the path to backend
  data,                        // the JavaScript array with data you want to pass
  onreadyfunc(result, errors), // the function is called when an answer is ready
  nocache                      // if set to TRUE, caching will be disabled
);

As you can see, there is nothing unnecessary in this function, we will always need to specify the path to backend (we can have several backends), we will always pass some data to server, and we will always react to the answer of server. Note that we do not use anything dependent on user's browser.

To send a file via AJAX, you will need to:

(See example below for details.)

In backend you get data from $_REQUEST or $_FILES array and put an answer to $_RESULT array.

JsHttpRequest converts JavaScript array data to PHP array $_REQUEST with the help of PHP itself ($_REQUEST is a standard array of input data used in non-AJAX scripts). It also puts the required information about uploaded files to $_FILES array, so you can use the standard mechanism of PHP file uploads.

Lyrical deviation 

You can freely pass multidimensional arrays from backend and to backend.

JsHttpRequest usage example

So, let's see some examples! We're going to write a fully-working AJAX application, which calculates MD5 of the entered string or the content of a selected file. We will use JsHttpRequest, of course.

For dummies 

MD5 is a popular cryptographical function, which returns unique identifier for any passed string data. It guarantees that this identifier will be different rather if two strings are quate large and differs in a couple of character. (More exact, a match probability is very-very small.) We can compare MD5 with human fingerprints: you cannot find two men with absolutely equal fingerprints.

FRONTEND (md5_frontend.htm)

Listing 4: test/JsHttpRequest/md5_frontend.htm copy code to clipboard
<script src="../../lib/JsHttpRequest/JsHttpRequest.js"></script>
<script language="JavaScript">
    // Function is called when we need to calculate MD5.
    function calculate_md5() {
        JsHttpRequest.query(
            'md5_backend.php', // backend
            {
                // pass a text value 
                'str': document.getElementById("mystr").value,  
                // path a file to be uploaded
                'upl': document.getElementById("myupl")
            },
            // Function is called when an answer arrives. 
            function(result, errors) {
                // Write errors to the debug div.
                document.getElementById("debug").innerHTML = errors; 
                // Write the answer.
                if (result) {
                    document.getElementById("ans").innerHTML = 
                        'MD5("' + result["str"] + '") = ' + result["md5"];
                }
            },
            false  // do not disable caching
        );
    }
</script>

<!-- Please note that we must specify enctype to multipart/form-data! -->
<form method="post" enctype="multipart/form-data" onsubmit="return false">
    Enter a text: <input type="text" id="mystr"><br>
    ...or upload a file: <input type="file" id="myupl"><br>
    <input type="button" value="Calculate MD5" onclick="calculate_md5()">
</form>

<div id="ans" style="border:1px solid #000; padding:2px">
    Structured results
</div>
<div id="debug" style="border:1px dashed red; padding:2px">
    Debug info
</div>

Don't be afraid of the size of frontend, we just cannot make it smaller as we write a fully-working application.

For dummies 

Associative arrays in JavaScript can be created using the following syntax:
my_js_array = { key1: value1, key2: value2, ... }
You can access properties either writing my_js_array.key1 or my_js_array["key1"].

You may also watch the work of this frontend online at here.

BACKEND (md5_backend.php)

Listing 5: test/JsHttpRequest/md5_backend.php copy code to clipboard
<?php
require_once "../../lib/JsHttpRequest/JsHttpRequest.php";
// Init JsHttpRequest and specify the encoding. It's important!
$JsHttpRequest =& new JsHttpRequest("windows-1251");
// Fetch request parameters.
$str = $_REQUEST['str'];
$upl = @$_FILES['upl'];
// Create the resulting array.
if (@$upl['tmp_name']) {
    // The file was successfully uploaded.
    $GLOBALS['_RESULT'] = array(
      "str"   => 'file ' . $upl['name'],
      "md5"   => md5(file_get_contents($upl['tmp_name'])),
    );
} else {
    // No file is uploaded, use the plain string.
    $GLOBALS['_RESULT'] = array(
      "str"   => $str,
      "md5"   => md5($str),
    );
}
// Everything we print will go to 'errors' parameter.
echo "<pre>";
?>
<b>QUERY_STRING:</b> <?=$_SERVER['QUERY_STRING'] . "\n"?>
<b>Uploaded files:</b> <?=print_r($_FILES, 1)?>
<?php
echo "</pre>";
// This includes a PHP fatal error! It will go to the debug stream,
// frontend may intercept this and act a reaction.
if ($_REQUEST['str'] == 'error') {
  error_demonstration__make_a_mistake_calling_undefined_function();
}
?>

You could have expected that our backend would be very large, but is not true! In backend we should not care about the way our information is displayed in browser: it is the task of a frontend.

You may download an archive demo.zip with all of the source code above, unpack it anywhere on your site and open http://your-site/path-to-demo/test/JsHttpRequest/md5_frontend.htm in your Web browser. (All samples are at the directory test/JsHttpRequest inside the downloaded archive.)

Work together with the Prototype library

Prototype is a very popular tool to simplify a JavaScript programmer's work. It includes AJAX support and other features. Library JsHttpRequest could be used as its server part in PHP (after inclusion of a small compatibility module JsHttpRequest-prototype.js). Even so, all additional features of JsHttpRequest (cross-browser compatibility, file uploading support, work with national charsets etc.) are still available.

Listing 6: Use typical Prototype functions copy code to clipboard
<script src="../../lib/JsHttpRequest/JsHttpRequest.js"></script>
<script src="../../lib/JsHttpRequest/JsHttpRequest-prototype.js></script>
<script language="JavaScript">
new Ajax.Request('your_ajax_script.php', {
  method: 'get',
  parameters: {
    name: 'Dmitry',  
    file: $("my_upload_file")
  },
  onFailure: function(tr) {
    alert('Error code: ' + tr.status + '\n');
    alert(tr.responseText);
  },
  onSuccess: function(tr) {
    $("result").innerHTML = tr.responseJS.hello; 
    if (tr.responseText) alert(tr.responseText);
  }
});
</script>

Of course you could use any other capabilities of the prototype for AJAX (e.g. functions for dynamic data loading into a HTML element).

Conclusion

Now you know that it is very easy to work with AJAX using JsHttpRequest. To know what else can you do with JsHttpRequest library, consider reading the following documents:

The JsHttpRequest library author thanks Yuri Nasretdinov for the first version of this article.


Страхование украина, автострахование, страховые комании украины | best online casino | Портал Goodgame - новости игры, стратегии, игры онлайн! | создание сайтов с эксклюзивным дизайном | Dedicated Аренда сервера быстрое подключение, качественный сервис


Dmitry Koterov, Dk lab. ©1999-2008
GZip
Add to Del.icio.us   Digg It!   Reddit