4

So I'm using plain javascript (no jquery), to send a file to the server. Server script PHP returns status code 200 at the end, but instead javascript is getting readyState == 2.

The PHP code sends back status code 200:

header('X-PHP-Response-Code: 200', true, 200);
exit;

The javascript is doing:

request.onreadystatechange = function() {
        if (request.readyState == 4) {
            var message;
            switch(request.status) {
                case '200':
                     message = "Data uploaded successfully.";
                break;

                case '406':
                    message = "Incorrect file format.  Please try again.";
                break;

                case '410':
                    message = "Unexpected error.  Please contact support.";
                break;

                default:
                break;
            }
            status_message_container.innerHTML = message;
            submit_button.disabled = false;
        }
        else {
            alert( "Unexpected error:  " + this.statusText + ".\nPlease try again");
        }
    };

    request.send(formData);

Even know the HTTP 200 status code comes back correctly (I get 'OK') on frontend. The JS script is seeing readyState==2 (i.e. else block always hit)

My understanding is that a server status code of 200 should give readyState == 4??

1 Answer 1

10

Firstly, onreadystate isn't just fired once. It's fired multiple times, you need to be able to handle that. These are the codes you need to handle:

0 UNSENT - open()has not been called yet
1 OPENED - send()has not been called yet
2 HEADERS_RECEIVED - send() has been called, and headers and status are available
3 LOADING Downloading; - responseText holds partial data
4 - The operation is complete

Your code is hitting the else block on readyState == 2 (headers received) and assuming that is an error status when it's not.

You error check should be inside the request.readyState == 4 check. That way, the request is complete but there could also have been an error:

if (request.readyState == 4) {
    switch(request.status) {
        case '200':
            message = "Data uploaded successfully.";
        break;
        // Error handling here
        default: alert( "Unexpected error:  " + this.statusText + ".\nPlease try again"); break;
    }
}

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

Sign up to request clarification or add additional context in comments.

4 Comments

I realise onreadystate hits multiple times - anytime readyState changes in fact. Specifically I'm wondering why readyState isn't 4 when I sent back HTTP 200? Isn't the operation completed by then? If not, what indicator does the server script have to give to get readyState == 4? EDIT: Your code will fail because readyState == 2 on HTTP status 200.
Your readyState probably did hit the completed block, eventually. It's just that it'll hit the "error" part first when it receives the error. It should always receive a done when a response is received - whether or not it's an error is defined by its response code. Updated answer to better explain that
My code won't fail. readyState is both 2 (when the headers are received) and 4 (when the response has been downloaded) when any status code is returned.
Is there any readystate will tell request is sent out successfully from OPENED? if readysate 2 means HEADERS_RECEIVED, means it got the response header already?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.