【问题标题】:Angular http$ response for text/plain file download fails with SyntaxError: Unexpected number in JSON文本/纯文件下载的 Angular http$ 响应失败,并出现 SyntaxError:JSON 中的意外数字
【发布时间】:2016-10-12 01:04:43
【问题描述】:

我基于以下解决方案在基于 Angular 的客户端和 node.js 后端实现了下载文件功能:https://stackoverflow.com/a/20904398/1503142。一般来说,这是可行的,但有时我会收到“SyntaxError:JSON 中位置 x 的意外数字”以及“TypeError:无法读取未定义的属性‘消息’”。

一些观察:

  • 节点服务器端似乎一切正常,因为我总是在客户端得到响应。有问题的错误由客户端报告;服务器未报告任何错误。
  • 日志文件由时间戳和基本日志信息文本组成。文本可以包含 ASCII 字符
  • 使用 Postman,响应每次都有效,这使人们认为可能是响应有问题的是 http$ 代码。 Postman的响应Header信息表明响应是Content-Type->text/plain; charset=utf-8。
  • 我正在使用 AngularJS v1.2.21 和 Node v0.12.13

这是客户端代码:

$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!')
});

这是服务器端代码:

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);
    }
  });
});

我怀疑这与日志文件的内容有关。既然我指定了 text/plain 内容,为什么会出现 JSON 解析错误?

【问题讨论】:

  • 需要在请求中设置dataType而不是header。请求标头没有意义,因为 GET 请求没有内容类型
  • 你能检查一下 mimetype 吗? mime.lookup(logDirectory + "/" + req.params.logfile)

标签: javascript angularjs node.js http get


【解决方案1】:

试试这个:

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

});

【讨论】:

  • 使用您的建议,我得到了完全相同的错误。我认为这进一步证明了这是一个客户端问题。虽然我承认这是更严格的代码。
【解决方案2】:

显而易见的答案是在发送之前对文件进行编码以确保安全通过,然后在浏览器中解码回文件内容。似乎某些特殊字符影响了客户端对传入数据的处理(可能是双引号):

所以在客户端,我现在正在这样做:

$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!')
});

服务器端是:

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));
    }
  });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    • 2022-01-26
    • 2015-03-08
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多