Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XMLHttp​Request​.upload.onprogress is triggered when server respons 500 error

I use XMLHttp​Request to upload a file. If server responds with error message 500, I try to handle error message before onprogress event.

XMLHttpRequest

const xhr = new XMLHttpRequest();

      xhr.onreadystatechange = function (oEvent) {
        if (xhr.readyState === 4) {
            if (xhr.status === 500) {
              console.log('error2');
            }
        }
    };

    xhr.onload = function() {
      if (this.status == 200) {
        console.log('success');
      }
    };

      xhr.upload.onprogress = function(e) {
        if (e.lengthComputable) {
          var percentComplete = (e.loaded / e.total) * 100;
          console.log(percentComplete);
        }
      };

      xhr.open("POST", "http://127.0.0.1:1337/upload-file", true);
      var formData = new FormData();
      formData.append("file", e.file);
      xhr.send(formData);

I throw error message on server on purpose:

const Koa = require('koa');
const Router = require('koa-router');
const cors = require('@koa/cors');
const serve = require('koa-static');
const path = require('path');
const koaBodyMultipart = require('koa-body')({ multipart: true });

const app = new Koa();
app.use(cors());
app.use(serve(path.join(process.env.PWD, '/dist')));

const router = new Router();

router
  .post('/upload-file', koaBodyMultipart, (ctx, next) => {
    const { file } = ctx.request.files;
    // if (file) {
    //     ctx.response.body = 'ok';
    // } else {
    //     ctx.throw(500,'Error Message');
    // }
    ctx.throw(500,'Error Message');
  });

app.use(router.routes()).use(router.allowedMethods());

// don't listen to this port if the app is required from a test script
if (!module.parent) {
  var server = app.listen(process.env.PORT || 1337);
  var port = server.address().port;
  console.log('running at port:' + port)
}

Why is upload.onprogress triggered before xhr.onreadystatechange and xhr.onload? How can I show error message before showing uploading progress?

like image 626
Matt Avatar asked May 31 '19 19:05

Matt


People also ask

What is XMLHttpRequest error?

This error is a Javascript error and it can be inspected from AndroidStudio terminal or from the browser console. If you run into this problem it means that the requests to the API server are failing due to a CORS error.

How do I fix XHR error?

How do I fix the XHR error? Technically, this is not error, it is normal response. The message tells you that you just tried to enter a secure room without the key, your error is that you don't have the key/authorization to enter that room. The only solution is to get the key/credentials and include on the request.

How do I upload a file using XMLHttpRequest?

Create the form object for submission The formData will contain the file object which can be easily appended. Then an AJAX request can be created by using XMLHttpRequest() method. This would be a POST request to /upload which is same as the one we mentioned while creating HTML form in Step 1.

How does XMLHttpRequest work?

XMLHttpRequest (XHR) objects are used to interact with servers. You can retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just part of a page without disrupting what the user is doing. XMLHttpRequest is used heavily in AJAX programming.


1 Answers

I wrote a simple script to check the order of events. The order of events always occurs this way:

readystateChange: 1
loadstart
XHR OPTIONS http://127.0.0.1:1337/upload-file [HTTP/1.1 204 No Content 24ms]
XHR POST http://127.0.0.1:1337/upload-file [HTTP/1.1 500 Internal Server Error 20ms]
progress
load
loadend
readystateChange: 2
readystateChange: 3
readystateChange: 4

Progress event is always triggered before the load events.

Since the progress is updated before your error message is displayed, you can update the progress upto a certain percentage like say 95%. Then handle the rest of the update in the loadend or readyStateChange events. For example:

xhr.upload.onprogress = function(e) {
    if (e.lengthComputable) {
        var percentComplete = (e.loaded - e.total*0.05 / e.total) * 100;
        percentComplete = percentComplete < 0? 0: percentComplete;
        console.log(percentComplete);
    }
};

xhr.onreadystatechange = function (oEvent) {
    if (xhr.readyState === 4) {
        if (xhr.status === 500) {
            // Handle error case
        } else if (xhr.status === 200){
            percentComplete = 100;
        }
    }
};
like image 94
TheChetan Avatar answered Oct 12 '22 13:10

TheChetan