Archive for the ‘Programming’ Category

IE6 AJAX hang on readyState 3

Tuesday, January 20th, 2009

I recently ran into a problem that took me a few days to find a work around for. Running a basic AJAX POST, IE6 would hang up on readyState 3 for 200 seconds, throw an “Unspecified Error“, and then finally perform the action. Having a user wait 200 seconds for the IE6 timeout to come into effect is simply not a solution. All other browsers I tested, including IE7, were not having this problem.

I read on the web that this may come from SSL or from compression on the webserver. I bypassed our SSL check entirely, and it still happened. I did not mess with the servers for http compression though. To me, that is NOT an option to disable. Bandwidth costs would be too much to even consider this a viable solution.

So, I returned to the programming aspect of it. There has to be a code fix somewhere.

Long story short, IE6 doesn’t handle connection closures properly. A typical request looks something like:


function doajax() {
var url = "/script.php";
var params = "x=123&y=456";

//add timestamp to pass a unique param each time to prevent ie caching the ajax object
timestamp = new Date();
tim1 = (timestamp.getTime());
sec1 = timestamp.getSeconds();
ms1 = timestamp.getMilliseconds();
thetime = tim1+sec1+ms1;

params += "&rand="+thetime

xmlHttp.open('POST',url,true);  
xmlHttp.onreadystatechange = alertContents;  
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader('If-Modified-Since','Tue, 04 Apr 2006 00:00:00 GMT');  //some date in the past
xmlHttp.setRequestHeader("Content-length", params.length);
xmlHttp.setRequestHeader("Connection", "close");
}
xmlHttp.send(params);

The line in question here is


xmlHttp.setRequestHeader("Connection", "close");

Since this header is effectively applied for each readyState, it ends up hanging up on readyState 3.

The easy fix:
Target ie6 (and other old browsers) to not close the connection.

change the above snippet to:


if(!document.all) {
  xmlHttp.setRequestHeader("Connection", "close");
}

I’m not 100% sure of the implications involved in NOT closing the connection, but I haven’t seen any performance impact, and this cleared up the bug right away. No JS errors, and no 200 second waiting. Give it a try and let me know if it works for you as well.

Freelance Programming Feedback

Monday, August 18th, 2008

This post contains comments from people whom I’ve done custom work for in the WordPress, vBulletin, and vBSEO worlds. I’ve asked those that I’ve worked with before to leave a few words here about my quality of work.

If I’ve done work for you, please leave a few words so others who are considering working with me know that I’m legit and can deliver as promised.

Thanks

WordPress Permalinks on IIS with ISAPI_Rewrite

Thursday, June 5th, 2008

I’ve run WordPress here on my CentOS box for nearly 4 years and am quite familiar with the software. Recently, I had a client on a Windows system request a blog be added to their web store. Their webstore is written in ASP and runs on windows. They wanted to stay on the same domain for SEO purposes, (thus site.com/blog/ instead of blog.site.com or a new .com). Without the subdomain or new IP, there’s no way to change DNS for a subdirectory to a different server. This meant I had to get it working on IIS.

Native installations for apache tend not to port well (or perhaps, easily) over to windows/IIS. Thankfully, ISAPI3 from HeliconTech.com supports .htaccess files and makes the job a little easier. WordPress works fine on windows/IIS until you want nice permalinks.

After MUCH searching, testing, and error log analysis, I’ve got a working solution for Windows Server 2003 with ISAPI_Rewrite 3.1.x, running php 5.2.x and mysql 5.0.x community.

  1. index.php should be set up in IIS as a default document (same place you find default.asp, index.htm, etc)
  2. edit wp-settings.php
    Find:
    <?php
    

    at the very top of the file.

    Replace with:

    <?php
    //*****************************
    //    IIS FIX
    //
    $_SERVER['REQUEST_URI'] = $_SERVER['HTTP_X_REWRITE_URL'];
    //*****************************
    
  3. create the following htaccess file with the Helicon Manager:
    
    RewriteEngine On
    
    #RewriteBase /
    
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule . - [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-.*) $2 [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
    RewriteRule . /blog/index.php [L]
    

    • Note: You may need to alter the RewriteBase or the last rule to your specific location. In my particular case, I was installed on domain.com/blog/

From here, you can edit your permalink structure as you normally would. If the default options has index.php/ as part of the rule, you can remove that.

Rand() isn’t Random

Wednesday, November 28th, 2007

If you use Microsoft SQL 2000, you’ve probably at one point had to pull random results. The built in rand() function simply doesn’t work. It gives you a random value the first time, and every time after it is the same it seems.

I found a new way to do this today after 20 pages of searching, so hopefully this will help someone else.

ORDER BY newid()

yup, it’s that simple.


SELECT
  TOP 2 
    field1
   ,field2
FROM
  TABLE
WHERE
  field1 = 1
ORDER BY
  newid()

To be noted, this will put a full table scan in place before it selects the top 2, so keep performance in mind.

Intro to CURL with PHP

Thursday, November 8th, 2007

CURL is a command-line style function to send data via a URL. WikiPedia has a more detailed article on what it is and does.

Preface – your php installation on your server must be CURL-enabled. You can download the CURL package for free. This article assumes your server is ready to go.

While CURL is not an alternative to AJAX, it can be used in similar situations where you need to send data out somewhere without the user having to go there. In it’s most basic operation, you have some data to send out to a script.

We need a a simple function to handle our data, a page to process said data, and a source page where the function is called from.

The call page is simple. Something as simple as:


<?php
print sendCURL($var1, $var2, $var3)
?>

where $var1 -3 are predefined, or even hard-coded strings will suffice for basic testing. This php block sets us up to print the output of our function:


function sendCURL($var1, $var2, $var3, $referrer="") {
  $mycurl = curl_init("http://domain.com/curl_processor_page.php"); 
  
  $fields = array(
    "var1" => $var1,
    "var2" => $var2,
    "var3" => $var3
  );

  $curlagent = array(
    "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
  );

  curl_setopt($mycurl, CURLOPT_POST, 1);
  curl_setopt($mycurl, CURLOPT_HEADER, 0);
  curl_setopt($mycurl, CURLOPT_NOBODY, 0); 
  curl_setopt($mycurl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); 
  curl_setopt($mycurl, CURLOPT_REFERER, $referer);
  curl_setopt($mycurl, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($mycurl, CURLOPT_SSL_VERIFYPEER, FALSE); 
  curl_setopt($mycurl, CURLOPT_HTTPHEADER, $curlagent);
  curl_setopt($mycurl, CURLOPT_POSTFIELDS, $fields); 

  $response = curl_exec($mycurl); 
  curl_close ($mycurl); 
  
  return $response;
}

This function is your basic CURL request. Setting the variables into an array to pass, and setting headers and Options within CURL on how to process it. The only real change you will need to make to this function are your variables in the array and your URL that you wish to send it to.

The curl_processor_page.php is no different than any other php page that can handle incoming $_REQUEST parameters. Those var’s need to be set up in the function that the page is looking for, perhaps a username, password, and a realname.

What that script does is entirely up to you. I won’t post an example, because I don’t want anyone to think that you can only do one method with this function set.

You could have the response be ANYTHING that gets returned from the processor page. A remote login, a simple welcome screen, or even creating accounts (how do you think those auto MySpace friend adder bots work?!)

A useful tool when playing with CURL is the LiveHTTP Headers plugin for FireFox. This plugin let’s you see what’s getting sent via HTTP AS it happens. It’s a real-time watchdog and is very useful for debugging CURL requests to see where it’s bombing.

Happy CURLing :)

Yahoo Releases YSlow

Wednesday, July 25th, 2007

YSlow is an add-on for the popular FireBug add-on for the popular browser, FireFox. Confused? :D

It has neat tools to help you to improve your site’s load times, and rates you accordingly. I scored an F on my blog. haha

Check it out: YSlow

BrainBench Certifications

Saturday, July 21st, 2007

I got an email tonight to take some free online tests. I took a couple, and scored pretty high in many areas, as I expected to, but also got stumped on a couple of the performance related issues (as I rarely deal with them). It’s fun to see how you compare to others who have taken the same test.

You can view my complete transcript here:

Brain Bench Transcript

HTML Programmer Cert

DB Cert

apache config

Getting a Global Array to work in a Function

Monday, July 9th, 2007

I recently spent a lot of time debugging this code i was working on for what I thought would be a simple onchange event.

The Issue:
I have sizes and colors, but not all sizes are available in all colors, so onchange of the color select box, i need to load the correct size options select box.

Between a lot of back-end manipulation, I was able to create my front-end JS arrays of colors with the sizes that are available. I ran into the issue that my passed in variable to the function was becoming the array, instead of calling the array.

For example, If I passed in “BLK” for Black, I was getting:


array[0] =>B
array[1] =>L
array[2] =>K
array[N] => undefined

where the Nth options looped through undefined until my for loop for the options of my color box’s length had been reached.

The Solution:
After scratching my head for hours and trying 232132 things, It turns out all I needed to do was to use the eval() function to evaluate my variable first, instead of treating it like a literal string.

Here’s the completed working source:



function popsizes(colorcode) {

var BLK= ["2XL","3XL","4XL","5XL","LG","MD","SM","XL","XS"];
var WH= ["LG","MD"];
// etc, many more color arrays

elem = document.getElementById("selcolor");
sizelist = eval(colorcode);

for (i=0; i<elem .options.length; i++) {
  document.getElementById("selsize").options[i] = new Option(sizelist[i]);
}
}

That script is powered by the onchange event from the form:


<tr>
  <td>
    <select "id="selcolor" name="color" onchange="popsizes(this.options[this.selectedIndex].value);">
      <option value="WH">White</option>
      <option value="BLK">Black</option>
      <option value=""> Many more colors, etc .... </option>
    </select>
  </td>
  <td>
    <select "id="selsize" name="size">
      <option value="">Select Color First</option>
    </select>
  </td>
</tr>

Scripting Around Poor Table Design

Tuesday, January 16th, 2007

We’ve all seen it. Some 3rd party database you’ve inherited from someone else was simply never designed with scalability and portability in mind. There’s no hope to change it, as it will break the original design and thus the original application that it is supporting.
(more…)

Quick SQL Date Functions and Queries

Friday, January 12th, 2007

It’s easy to grab the date from a field in a database so long as you saved a timestamp field along with your data row. However, there are often times in developing stored procedures and advanced queries where one needs to look up events in the future, or past based on some other reference point from either the data at hand, or an arbitrary date, such as in a calendar.
(more…)