我试图通过Google Docs API通过Nodejs Express服务器提供PDF文件(在上下文中,这是一份简历)。我能够轻松地使用HTML,文本和rtf文件来完成此操作。我无法使用PDF和其他格式(例如zip,doc)来完成此操作(也许是因为它们是二进制文件类型)
macOS Mojave | nodejs v10.15.0 | express.js v4.17.0 | Chrome v74.0.3729.157
我最初设置了Google Docs API,并使用text / plain调用了drive.files.export
函数,然后在res.send中传递了result.data(我的简历的纯文本版本的字符串)。这有效√
接下来,我做了同样的事情,但是我设置了头文件res.setHeader("Content-disposition", "attachment; filename=resume.txt");
,并且再次起作用了;我可以在浏览器中下载文本文件。 √
我再次尝试了相同的操作,这次将“ application / rtf”传递给Google Docs API,然后在响应中设置了适当的标头,因此我能够获得简历的rtf版本。 √
在这里事情对我不起作用...
下一个合乎逻辑的步骤是对PDF进行相同的设置,就像我对RTF一样设置所有标题。下载的文件大小与我预期的差不多,并且在Node.js中没有出现任何错误,但是文件无效(无法在任何应用程序中打开)。我对.doc,.zip和其他几个尝试过相同的方法。没有运气。
我读过一些文章,人们在其中将数据传送到写流中并将文件保存到他们的服务器中。我不想这样做。
大多数其他资源都在说明如何从服务器上的公用文件夹下载公用pdf文件。也不是我想要的。
当我从Google Docs控制台记录响应对象时,我得到一个对象,其中包含一堆请求标头和文件元数据,以及一个包含所有原始数据的“数据”对象。文本格式的数据看起来像人类可读数据一样,二进制格式的数据看起来像乱码一样。
与我取得的进展最接近的是我尝试使用.zip格式时,我能够下载一个zip存档,我可以(仅)通过终端将其解压缩,它将产生一个空白文件,但至少具有正确的文件名名称。这可能是因为zip文件包含有关其包含的文件的纯文本指令,因此未损坏。
RTF文件的工作示例代码:
router.get("/rtf", (req, res) => {
const docData = googleapi.getGoogleDocs("application/rtf");
docData.then(dd => {
res.setHeader("Content-Type", "application/rtf");
res.setHeader("Content-Disposition", "attachment; filename=resume.rtf");
res.send(dd.data);
});
});
// ... some auth stuff, Promises, etc ...
getGoogleDocs(mimeType) {
return drive.files
.export({
fileId: "XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx",
mimeType: mimeType
})
.then(fileData => {
return fileData;
});
}
我尝试了各种方法来获得与PDF相同的成功。几乎所有组合都会导致下载的文件无效/损坏:
router.get("/pdf", (req, res) => {
const docData = googleapi.getGoogleDocs("application/pdf");
docData.then(dd => {
// Tried various headers:
res.setHeader("Content-Type", "application/pdf");
// res.setHeader("Content-Type", "application/octet-stream");
res.setHeader(
"Content-Disposition",
"attachment; filename=resume_html.zip"
);
// Setting the content length based on the meta-data from
// the Google Docs API payload
res.setHeader("Content-Length", "476");
// Tried various ways to send the response:
// res.setHeader("Content-Transfer-Encoding", "binary");
res.end(dd.data, "binary");
});
});
..以及围绕Google Docs API调用的修改后的代码...
const aPromise = new Promise((resolve, reject) => {
drive.files.export(
{
fileId: "XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx",
mimeType: mimeType
},
{ encoding: null },
(err, buffer) => {
// There were no errors.
err ? reject(err) : resolve(buffer);
// return buffer;
}
);
});
return aPromise;
建议添加'encoding:null'作为防止破坏二进制数据的一种方法。我不确定如果数据位于字符串格式的响应对象中,那将有什么帮助。
预期结果:我可以下载有效的PDF文件。
实际结果:我得到一个文件,其中包含从Google Docs API接收的数据,可能是原始的PDF数据,但不会导致下载有效/可识别的pdf文件。