通过Nodejs Express Server检索时,生成的SSRS PDF返回空白



长时间读者,第一次海报。

我正在尝试使用nodejs Server(Express)作为中间的服务层生成一个从SSRS生成PDF文件,并将其提供给最终用户。我们不想将任何与SSR有关的内容揭露给用户,因此我将节点服务器放在一起并使Get request of to Server。

问题是,我可以通过SSR的响应主体获取PDF并将其传递到HTML页面,但是尽管页面计数和文件大小是正确的,但文件完全空白。即使我将数据写入文件作为测试,也会发生这种情况。

在Web浏览器中使用Postman或curl或从Chrome进行直接获取请求时,它将文件成功加载为附件,而没有正体。但是,当我通过节点进行相同的获取请求时,我会得到一个标题,声称有一个附件以及一个包含PDF代码的正文,我只能想象它在击中我的节点服务器时已转换为UTF-8编码。因为该报告是通过SSR生成的,所以我无法使用Express的响应。Download()或类似的功能主义者,因为我在生成PDF之前没有确切的路径。

使事情变得更加复杂,我必须依靠限于HTTP-NTLM库中的请求来从我们的SSRS服务器中获取响应,因此,我无法获得最大的知识,因此,管道和类似的方法是我无法获得的。。我之所以选择这主要是因为它允许我通过HTTP而不是https访问SSR(我们的SSR配置对HTTPS没有响应)。

节点服务器函数:

exports.getReportPDF = function (req, resp)
{
//-Gets the link info from the client side
var myLink = req.body;
var fileLink = myLink.Data;
httpntlm.post({
    url: fileLink,
    username: 'username',
    password: 'password',
    workstation: 'workstation',
    domain: 'domain'
}, function (err, res){ //-Returns once the stream is complete
    if(err) return err;
    var resBase64 = new Buffer(res.body).toString('base64');
    resp.setHeader('Content-Type', 'application/octet-stream');
    resp.setHeader('Content-Transfer-Encoding', 'base64');
    fs.writeFile("somethingToCheckAgainst.pdf", resBase64, function(writeErr) {
     if(writeErr) {
            console.log(writeErr);
        } else {
            console.log("The file was saved!");
        }
    });
    console.log(resp.get('Content-Disposition'));
    resp.send(resBase64);
});
}

客户端功能部分:

xmlhttp.onreadystatechange = function()
{
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
        var results = xmlhttp.responseText;
        window.open("data:application/pdf;base64, " + results);
    }
}

这是一个快速而肮脏的原型,因此我不关心速度和凌乱的代码,但首选干净而简单。如何获得在新窗口中打开的PDF,或在服务器上创建的窗口打开的PDF以正确显示(不是完全空白)?这是节点与SSR的数据相互作用的问题,还是由我处理数据的方式引起的?

我在相当长的一段时间内遇到了同样的问题。试图成为一个好公民,并在经过几天的故障排除后发布了什么为我解决的问题,因为答案似乎没有出现在互联网上的其他任何地方。

在httpntlm.post中,添加另一个选项 - "二进制:true"。如果您不这样做,则发现响应。Body会自动转换为UTF-8字符串,该字符串损坏PDF并导致其显示为空白。

即使http-ntlm没有为您提供流式传输的选项,也不需要将数据写入磁盘,也不需要将其编码为base64。您可以简单地创建自己的可读流。替换的resumer NPM模块使其变得既干净又干净。将其工作到您的NTLM回调中,看起来像这样:

var resumer = require('resumer');
function (err, res){ //-Returns once the stream is complete
    if(err) return next(err);
    var buffer = new Buffer(res.body);
    var stream = resumer().queue(buffer).end();
    resp.setHeader('Content-disposition', 'attachment; filename=out.pdf');
    resp.setHeader('Content-type', 'application/pdf');
    stream
        .pipe(resp)
        .on('error', next);
};

还请注意,我正在使用第三个中间件参数next来处理任何错误。只需像您那样做if(err) return err;,这无济于事。

相关内容

  • 没有找到相关文章

最新更新