Tuesday, 2 May 2017

node.js (React + Koa) CORS request giving: Error: request size did not match content length

Heyas, I know this is a farely common problem, but I keep getting inconsistent responses in my application.

I basically have two apps running locally on different ports, one is the web app, the other the API. Because of the different ports, I'm requesting from the API as CORS.

Here's my javascript code (using the npm xhr library. I've also tried the native fetch API, but it's giving the same response):

    var opts = {
        method: type,
        headers: {},
        useXDR: true
    };

    console.log("Fetch", url, opts)

    xhr(url, opts, function(err, resp) {
        if (err) {
            console.log("REQUEST ERROR", err, this.url);
            return reject(err);
        }
        ...
    }

The requests preflight with an OPTIONS request, and my code handles this by responding with a 200 status, then the regular POST request is sent. Here's the response that the server is giving:

  <-- OPTIONS /api/trip/new
APP ERROR { [Error: request size did not match content length]
  expected: 27,
  length: 27,
  received: 0,
  message: 'request size did not match content length',
  status: 400,
  statusCode: 400,
  type: 'request.size.invalid',
  expose: true } Error
    at /Users/rw3iss/Sites/testapp/api/system/startup.js:29:35
    at run (/Users/rw3iss/Sites/testapp/node_modules/core-js/modules/es6.promise.js:87:22)
    at /Users/rw3iss/Sites/testapp/node_modules/core-js/modules/es6.promise.js:100:28
    at flush (/Users/rw3iss/Sites/testapp/node_modules/core-js/modules/_microtask.js:18:9)
    at nextTickCallbackWith0Args (node.js:420:9)
    at process._tickDomainCallback (node.js:390:13)
  --> OPTIONS /api/trip/new 400 5ms 72b

I don't understand why this is happening, because the 'expected' and 'length' properties of the response match, contradicting the error.

Furthermore, the error only seems to happen when I set some headers on the request, ie. the Authorization header:

opts.headers["Authorization"] = token;

I'm not sure if it should matter, but the server is (trying) to send back these headers with each response (ie. for OPTIONS and the POST):

app.use( async (ctx, next) => {
      ctx.set('Access-Control-Allow-Origin', config.domain);
      ctx.set('Access-Control-Expose-Headers', 'true');
      ctx.set('Access-Control-Allow-Credentials', 'true');
      ctx.set('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
      ctx.set('Access-Control-Allow-Headers', 'Cache-Control,Content-Type,X-Requested-With,Authorization,Access-Control-Allow-Headers');

      console.log("FIRST REQUEST", ctx.method);

      if (ctx.method == 'OPTIONS') {
         console.log("IS OPTIONS REQUEST");
         return ctx.status = 200;
      } else {
         await next();
      }
   });

Could anyone possibly help please?



via Ryan Weiss

No comments:

Post a Comment