1

I have implemented a download file feature on my Angular-based client and node.js backend based on the following solution: https://stackoverflow.com/a/20904398/1503142. In general this works, but sometimes I receive a "SyntaxError: Unexpected number in JSON at position x" combined with a "TypeError: Cannot read propery 'messages' of undefined".

A few observations:

  • Everything appears to be working on the node server-side, because I do always get a response at client. The error in question is reported by the client; no errors are reported by the server.
  • The log file consists of a time stamp, then basic log information text. The text could contains ASCII characters
  • Using Postman, the response works every time, which lends itself to the idea that it is the http$ code that might be having an issue with the response. Postman's response Header information indicates that the response is Content-Type->text/plain; charset=utf-8.
  • I am using AngularJS v1.2.21 and Node v0.12.13

Here's the client-side code:

$http({
    method: 'GET',
    url: "/api/logging/logfiles/" + logFile,
    headers: { 'Content-Type': 'text/plain;charset=utf-8' }
}).
success(function (data, status, headers, config) {
    var anchor = angular.element('<a/>');
    anchor.attr({
        href: 'data:text/plain;charset=utf-8,' + encodeURIComponent(data),
        target: '_blank',
        download: logFile
    })[0].click();
}).
error(function (data, status, headers, config) {
    console.log('Hence my visit to StackOverflow!')
});

Here's the server-side code:

app.get('/api/logging/logfiles/:logfile', function (req, res, next) {
  logDirectory = './log';
  fs.readFile(logDirectory + "/" + req.params.logfile, 'utf8', function (err, data) {
    if (err) {
        res.send("Something broke!");
    }
    else {
        res.set({ 'Content-Type': 'text/plain; charset=utf-8' });
        res.send(data);
    }
  });
});

I suspect that this is related to the contents of the log file. Since I've specified text/plain content, why would there be a JSON parsing error?

Community
  • 1
  • 1
HiDefLoLife
  • 555
  • 1
  • 8
  • 28
  • 1
    need to set dataType not header in request. The request header is meaningless since there is no content type for a GET request – charlietfl Jun 11 '16 at 01:49
  • can you check the mimetype? mime.lookup(logDirectory + "/" + req.params.logfile) – eenagy Jun 11 '16 at 08:11

2 Answers2

0

Try this :

app.get('/api/logging/logfiles/:logfile', function (req, res, next) {
  logDirectory = './log';
  res.sendFile(logDirectory + "/" + req.params.logfile);

});
eenagy
  • 912
  • 1
  • 8
  • 22
  • Using your suggestion, I got the exact same error. I think this is further proof that this is a client-side issue. Though I admit it is tighter code. – HiDefLoLife Jun 13 '16 at 18:43
0

The obvious answer was to encode the file before sending to ensure safe passage, then decode back to file contents at the browser. It appears that some special character(s) was/(were) affecting client-side handling of the incoming data (likely double-quotes):

So on the client-side, I'm now doing this:

$http({
  method: 'GET',
  url: "/api/logging/logfiles/" + logFile
  // Removed unncessary dataType based on charlietfl's comment
}).
success(function (data, status, headers, config) {
  var anchor = angular.element('<a/>');
  anchor.attr({
    // decode the file to go back to raw data
    href: 'data:text/plain;charset=utf-8,' + decodeURI(data),
    target: '_blank',
    download: logFile
  })[0].click();
}).
error(function (data, status, headers, config) {
  console.log('Hence my visit to StackOverflow!')
});

The server-side is:

app.get('/api/logging/logfiles/:logfile', function (req, res, next) {
  logDirectory = './log';
  fs.readFile(logDirectory + "/" + req.params.logfile, 'utf8', function (err, data) {
    if (err) {
       res.send("Something broke!");
    }
    else {
      res.set({ 'Content-Type': 'text/plain; charset=utf-8' });
      // Encode the data to remove characters that might
      // present issues to the client
      res.send(encodeURI(data));
    }
  });
});
HiDefLoLife
  • 555
  • 1
  • 8
  • 28