我在Firebase函数中编写代码,充当两个数据库之间的中介。 (我已被授权这样做。)
我需要将一些用户数据和一些PDF从数据库1发送到数据库2.除了PDF之外,我还能正常工作。数据库2中存在具有正确页数的PDF,但问题是用户门户中的PDF以及从数据库下载时都显示为空白。
数据库1向我发送PDF的base64编码字符串。我不知道我应该向数据库2发送什么。数据库2在Ruby中有一个API和非常稀疏的文档;它们仅提供示例,并且对API的支持很少。以下是迄今为止我无法弄清楚的部分:
post_body << "--#{BOUNDARY}\r\n"
post_body << "Content-Disposition: form-data;
name=\"document[attachments_attributes][0][attachment]\";
filename=\"document.pdf\"\r\n"
post_body << "Content-type: application/pdf \r\n"
post_body << "\r\n"
post_body << File.read(file)
post_body << "\r\n--#{BOUNDARY}--\r\n" # the last boundary is prefixed and suffixed
with --
&#13;
我真正知道的部分是File.read(file)
。我不知道如何从base64字符串中获取该方法在NodeJS环境中返回的等价物。我在IRB中尝试了File.read(file).encoding
并返回了UTF-8,所以我尝试了Buffer.from(base64String, 'base64').toString('utf8')
,但这没有用。
我已经尝试了我可以通过该方法传递的所有编码(&#39; ascii&#39;(7位),&#39; utf8&#39;,&#39; utf16le&#39;, &#39; latin1&#39;,&#39; binary&#39;,&#39; hex&#39; - nodejs.org/api/buffer.html#buffer_class_method_buffer_from_array)。他们都没有工作。我尝试将UTF-8字符串转换为一串JavaScript转义序列。我试过了this package。我用Google搜索common encodings in Ruby并看到8位ASCII就是其中之一,所以现在我试图在NodeJS中将base64转换为8位ASCII。
如果您对我未正确行事有所了解,那就太棒了。或者,如果您不知道如何将base64转换为8位ASCII,那也很棒。
下面是File.read(文件)在IRB中返回的片段:
Creator(շ\x8Fc\\(t~\xC8\u0018\u0005\xA6\x8F\xB8\xD2\u0017\x8C\u0014\x87b\u0004\xE8\xB4ΐ<Έ\b)/Producer(շ\x8Fc\\(t~\xC8\f\\(\x93\xB6\xB0\xD5\u001E\x9BF\x90{\u001A\xF6\xAD\xFB\xE8\xD0\xEB\xD9\u0005ŕ\ew\xF3)/ModDate(\xD0\xEE\xCF<z-:\xDExu\xD1\xF7\xED\x8EA\xC8\u0019\x80{\u0013\xF6\xB3\xE9)/Company(ӻ\x8Bi8{g\x8D&5\xC0\xAD\xBF\x99+\x8B_\xDF\")/SourceModified(\xD0\xEE\xCF<z-:\xDExu\xD2\xF0\xED\x8BG\xC8)/Title(\xB4\x84\xB9JjAo\x9B<a\xB0\xA3\xBE\xDC)>>\rendobj\rxref\r\n0 37\r\n0000000000 65535 f\r\n0000014115 00000 n\r\n0000014965 00000 n\r\n0000014998 00000 n\r\n0000015021 00000 n\r\n0000015072 00000 n\r\n0000019484 00000 n\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535 f\r\n0000000000 65535
&#13;
它看起来像是一些带有一些转义序列的ASCII字符。
以下是更多示例,如果您需要它:
#!/usr/bin/env ruby
require "net/http"
require "time"
require "digest"
require "openssl"
require "base64"
# Token used to separate each Content Part. This string should be a
# random string and not appear in the file body.
BOUNDARY = "MultipartBoundary"
uri = URI.parse "https://kipuapi.kipuworks.com/api/patients"
file = "spec/fixtures/files/document.pdf"
post_body = ""
post_body << "--#{BOUNDARY}\r\n" # boundaries are prefixed with --
post_body << "Content-Disposition: form-data;
name=\"document[data][first_name]\"\r\n"
post_body << "\r\n"
post_body << "John"
post_body << "\r\n"
post_body << "--#{BOUNDARY}\r\n" # boundary's prefixed with --
post_body << "Content-Disposition: form-data;
name=\"document[data][last_name]\"\r\n"
post_body << "\r\n"
post_body << "Smith"
post_body << "\r\n"
post_body << "--#{BOUNDARY}\r\n"
post_body << "Content-Disposition: form-data; name=\"document[recipient_id]\"\r\n"
post_body << "\r\n"
post_body << @access_id # sending to ourselves
post_body << "\r\n"
post_body << "--#{BOUNDARY}\r\n"
post_body << "Content-Disposition: form-data; name=\"app_id\"\r\n"
post_body << "\r\n"
post_body << @access_id
post_body << "\r\n"
post_body << "--#{BOUNDARY}\r\n"
post_body << "Content-Disposition: form-data;
name=\"document[attachments_attributes][0][attachment]\";
filename=\"document.pdf\"\r\n"
post_body << "Content-type: application/pdf \r\n"
post_body << "\r\n"
post_body << File.read(file)
post_body << "\r\n--#{BOUNDARY}--\r\n" # the last boundary is prefixed and suffixed
with --
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.body = post_body
request["Content-Type"] = "multipart/form-data, boundary=#{BOUNDARY}"
request["Accept"] = "application/vnd.kipusystems+json; version=1"
request["Date"] = Time.now.httpdate
request["Content-MD5"] = Digest::MD5.base64digest request.body
canonical_string = [
request["Content-Type"],
request["Content-MD5"],
uri.request_uri,
request["Date"]
].join ","
digest = OpenSSL::Digest.new "sha1"
signed = OpenSSL::HMAC.digest digest, @secret_key, canonical_string
encoded_sig = Base64.strict_encode64 signed
19 / 23
request["Authorization"] = "APIAuth #{@access_id}:#{encoded_sig}"
response = http.request request
puts response.body
&#13;
以下是Firebase中相关代码的一部分(请注意,当时我编写了一个函数来处理所有get和所有post请求,认为这将是一个小项目,我现在后悔),
function createReq(uri, body, credObj, method, multipart, res){
if (multipart){
let postBody = '';
let dataObj = body.document.data;
let attachmentsArr = body.document['attachment_attributes'];
// formatting data in dataObj, appending to postBody
for (let i = 0; i < attachmentsArr.length; i++){
postBody += '--'+BOUNDARY+'\r\n';
postBody += 'Content-Disposition: form-data; ';
postBody += 'name="document[attachments_attributes]['+ i +'][attachment]'+'"; ';
postBody += 'filename="'+ attachmentsArr[i]['filename'] + '"\r\n';
postBody += 'Content-type: ' + attachmentsArr[i]['content_type'] +' \r\n';
postBody += '\r\n';
// TODO: need to do something with the base64 attachment string here
//console.log(attachmentsArr[i]['attachment']);
if (i === attachmentsArr.length - 1){
postBody += '\r\n--'+BOUNDARY+'--\r\n';
}
} // closes attachmentArr loop
// authentication code, define variables signature and contentStr
let reqObj = {
url: ROOT_URL+uri,
method: 'POST',
headers: {
'Content-type': 'multipart/form-data, boundary='+BOUNDARY,
'Accept': ACCEPT_HEADER_VALUE,
'Authorization': 'APIAuth '+credObj.accessId+':'+signature,
'Date': new Date().toUTCString(),
'Content-MD5': contentStr
},
body: postBody
};
return reqObj;
} else // other code for non-multipart post requests
}
&#13;
返回的reqObj在我的承诺中被发送到数据库2: (我已经注释掉了将请求发送到数据库2的代码)
...
}).then(reqObj => {
// code for get method
// ...
else if ('POST' === method){
reqObj.method = 'POST';
console.log('THIS IS REQUEST OBJ INSIDE LAST PROMISE');
console.log(reqObj);
// request.post(reqObj, function(error, response, body){
// if (!error){
// console.log('THIS IS RESPONSE FROM KIPU');
// console.log(body);
// res.send(body);
// } else {
// console.log(error);
// res.send(error);
// }
// });
}
}).catch(err => {
res.send(err);
});
&#13;