我们正在开发具有Recurly集成的应用程序,并尝试使用它的PDF Invoice功能。
该应用程序基于Node.js(流星平台)。
它使用二进制文件从Recurly接收正确的答案:
但是我无法正确保存它。我尝试了两种方法:在浏览器的客户端上打印它:
var file = window.URL.createObjectURL(new Blob([r.content], {type: "application/pdf"}));
var a = document.createElement("a");
a.href = file;
a.download = "invoicePDF";
document.body.appendChild(a);
a.click();
window.onfocus = function () {
document.body.removeChild(a)
}
并将其直接保存在服务器上(仅用于测试):
var fs = require('fs');
var wstream = fs.createWriteStream('C:/recurly.pdf');
wstream.write(result.content);
wstream.end();
但是在两种情况下,我最终都无法使用pdf文件。Acrobat,Foxit阅读器和Chrome无法打开此文件-已损坏。
你有什么建议我错了吗?也许我需要先进行一些内容转换,然后再保存它或进行其他操作?
添加
我已将此请求发送给客户端并打印在控制台中(上图)。
try {
result = HTTP.call(
'GET',
'https://' + Meteor.settings.recurly.SUBDOMAIN + '.recurly.com/v2/invoices/' + invoiceId,
{
headers: {
Authorization: "Basic " + (new Buffer(Meteor.settings.recurly.API_KEY)).toString('base64'),
Accept: 'application/pdf'
}
}
);
} catch (err) {
result = e;
}
问题是您正在尝试获取一个带有请求的二进制文件,该请求期望将编码的字符串作为响应。
最好的选择是告诉请求库它应该期待什么,否则,您将不得不手动从UTF-16
-或UTF-8
-encoded字符串中撬出二进制数据。
客户端和服务器实现之间有区别。
服务器实现使用节点的request
模块。你可以它为供应选择使用npmRequestOptions
。
如其文档中所述:
encoding-用于响应数据的setEncoding的编码。如果为null,则将正文作为Buffer返回。其他任何内容(包括默认值undefined)都将作为编码参数传递给toString()(这意味着默认情况下它实际上是utf8)。(注意:如果需要二进制数据,则应将编码设置为:null。)
因此,在服务器上,您可以执行以下操作:
try {
result = HTTP.call(
'GET',
'https://' + Meteor.settings.recurly.SUBDOMAIN + '.recurly.com/v2/invoices/' + invoiceId,
{
headers: {
Authorization: "Basic " + (new Buffer(Meteor.settings.recurly.API_KEY)).toString('base64'),
Accept: 'application/pdf'
},
npmRequestOptions: {
encoding: null // will cause the result to be stored in a binary Buffer
}
}
);
// will write the file in binary mode
fs.writeFile(outFileName, res.content, 'binary');
} catch (err) {
result = e;
}
客户端实现使用XHR。
为了处理二进制响应,您需要将XHR更改responseType
为(最好是)'blob'
。
不幸的是,我看不到Meteor当前HTTP包实现中的二进制blob,因为它希望响应包含一个responseText
。
您可以直接使用XMLHttpRequest
对象,但可能需要添加一些包装程序代码以支持即将死去的浏览器(IE6,我在看着您!-通常是new ActiveXObject('Microsoft.XMLHttp');
跳舞)。
这可以使用以下代码来实现:
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.setRequestHeader('Authorization', ...);
xhr.responseType = 'blob'; // this is key
xhr.onload = function(e) {
if (this.status == 200) {
// this.response is a Blob. If you are sure that it is of the
// correct content-type, you can use it to construct the URL directly
let blob = new Blob([this.response], {type: 'application/pdf'});
let url = URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = "invoice.pdf";
document.body.appendChild(a);
...
}
};
xhr.send();
它发送一个XHR,该XHR将响应编码为二进制Blob,并生成带有正确数据的ObjectURL。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句