Skip to content

June 1, 2010

Note on implementing Ajax style hidden IFRAME upload page on FreeBSD 8.0

by Joe Kuan

This problem has taken me a while to track it down. The same code works fine on Ubuntu with IE8, Firefox, Safari but it just doesn’t work on FreeBSD.

For details of implementing a Ajax style upload page, see this. Basically, you have a page with a FORM and a IFRAME, following is an example:

<FORM action='install_upload.php' method=post enctype='multipart/form-data' target=hidden_upload >
<input type=file name='upload_file' >
<INPUT type=submit name=submit value=Upload onclick='return checkUpload();' />
<IFRAME id=hidden_upload name=hidden_upload src='' onLoad='uploadDone( )'
               style='width:500;height:300;border:0px solid #fff'>

In this case, I have set the hidden frame dimension to non-zero, so I can see how is happening in behind.

On the PHP side, the install_upload.php is called as soon as the upload is finished and the JSON result is outputed to the hidden IFRAME.

// Some code here to get the install process status and perhaps some log messages
// and assign the result into the $result array
// move_uploaded_file($_FILES[....], ....)
// unpack uploaded file
// run install process in the background
echo json_encode($result);

Once the output text is pushed into the IFRAME, the onLoad event is triggered and Javascript function uploadDone is called. The uploadDone is based on the code in OpenJS.


When I upload a file on IE8 browser, I get a message,  “Do you want to save this file, or find a program….”. This is totally unexpected, so I looked in the content of the install_upload.php which is the JSON output, very strange.

As for Safari and Firefox, the uploadDone function did not work and reported with a Javascript error but what inside the IFRAME looks legitimate JSON text to me. When I tried to call alert with the content inside the IFRAME. Then it became clear. The JSON text was encapsulated inside a <PRE> tag.


After a very long while of investigation, I realise the problem is to do with the PHP’s JSON implementation. On FreeBSD 8.0, the PHP JSON has to be installed as a separate PEAR package. The methods json_encode and json_decode are not part of the PHP installation. So I have to do something like this within my web application.

  if ( !function_exists('json_decode') ) {
    function json_decode($content, $assoc=false){
      require_once 'JSON.php';
      if ( $assoc ){
        $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
      } else {
        $json = new Services_JSON;
      return $json->decode($content);

  if ( !function_exists('json_encode') ){
    function json_encode($content){
      require_once 'JSON.php';
      $json = new Services_JSON;
      return $json->encode($content);

Look inside the JSON.php file (/usr/local/share/pear/JSON.php),  here is the code for the encode function:

function encode($var)    {
        header('Content-type: application/x-javascript');
        return $this->_encode($var);

The header function call is the culprit which causes all the problems within the IFRAME. However, there is another function within the JSON package which does:

function encodeUnsafe($var) {
        return $this->_encode($var);

As soon as I make sure calling encodeUnsafe inside the install_upload.php, all the problems gone away.

I work for iTrinegy. Here are my other blogs on FreeBSD


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments

%d bloggers like this: