如何将 pdf 保存到 Cloudant

分享于2022年07月17日 axios cloudant javascript vue.js 问答
【问题标题】:如何将 pdf 保存到 Cloudant(How to save pdf to Cloudant)
【发布时间】:2022-06-11 02:16:23
【问题描述】:

我想将 pdf 保存到 Cloudant。使用下面的代码,在 Cloudant 中打开附件时出现错误。 “处理此文件时遇到错误” 我可以将假字符串数据放在“._attachments[name].data”字段中,它会保存。

Cloudant 文档说数据内容需要采用 base64 格式,这就是我正在尝试的。 Cloudant 说“必须使用 BASE64 表示提供内容”

 function saveFile() {
      var doc = {};
      var blob = null;
      //fileName is from the input field model data
      var url = fileName;
    
  fetch(url)
    .then((r) => r.blob())
    .then((b) => {
      blob = b;
      return getBase64(blob);
    })
    .then((blob) => {
      console.log(blob);
      let name = url._rawValue.name;

      doc._id = "testing::" + new Date().getTime();
      doc.type = "testing attachment";

      doc._attachments = {};
      doc._attachments[name] = {};
      doc._attachments[name].content_type = "application/pdf";
      doc._attachments[name].data = blob.split(",")[1];
      console.log("doc: ", doc);
    })
    .then(() => {
      api({
        method: "POST",
        url: "/webdata",
        auth: {
          username: process.env.CLOUDANT_USERNAME,
          password: process.env.CLOUDANT_PASSWORD,
        },
        data: doc,
      })
        .then((response) => {
          console.log("result: ", response);

          alert("Test has been submitted!");
        })
        .catch((e) => {
          console.log("e: ", e);
          alert(e);
        });
      console.log("finished send test");
    });
}
function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });
}

有什么想法吗? 谢谢


【解决方案1】:

CouchDB 以及 Cloudant 的扩展具有处理“多部分”请求的方法,其中 JSON 文档和附件在同一个请求中发送。见 https://docs.couchdb.org/en/3.2.2/api/document/common.html#put--db-docid

它们在此处以 CouchDB 的 Nano 项目为模型: https://www.npmjs.com/package/nano#multipart-functions

const fs = require('fs');

fs.readFile('rabbit.png', (err, data) => {
  if (!err) {
    await alice.multipart.insert({ foo: 'bar' }, [{name: 'rabbit.png', data: data, content_type: 'image/png'}], 'mydoc')
  }
});

或者,您可以先编写文档,然后在补充请求中添加附件。使用当前的 Cloudant SDK:

const doc = {
  a: 1,
  b: 2
}
const res = await service.putDocument({
  db: 'events',
  docId: 'mydocid',
  document: doc
})
const stream = fs.createReadStream('./mypdf.pdf')
await service.putAttachment({
  db: 'events',
  docId: 'mydocid',
  rev: res.result.rev,  // we need the _rev of the doc we've just created 
  attachmentName: 'mypdf',
  attachment: stream,
  contentType: 'application/pdf'
})

  • 谢谢,@glynn-bird,我在 questin 中的代码似乎有效。它保存一个附件。
  • 谢谢,@glynn-bird,我在问题中的代码似乎有效。它保存一个附件。但是当我尝试在 Cloudant 中打开附件时,我得到了问题中的错误。我注意到无论我上传使用什么文件,我发送的数据似乎都是一样的