node.js - 从 Lambda 上传的 AWS S3 返回空白 PDF (Node.js)

标签 node.js pdf amazon-s3 aws-lambda docusignapi

我有一个使用 Axios 的 Lambda,使用其 REST API 从 DocuSign 获取 PDF:

const url = `${base_uri}/restapi/v2.1/accounts/${account_id}/envelopes/${envelope_id}/documents/combined`;
const res = await axios.get(url, { headers: { Authorization: `Bearer ${token}` } });

基于我在 res 中看到的内容标题,PDF 采用 UTF-8 编码:

headers: {
  'content-type': 'application/pdf',
   ...
  'content-disposition': `file; filename="Test1.pdf"; documentid="combined"; filename*=UTF-8''Test1.pdf`,
   ...
}

res.data是 PDF 的内容 & 是一个字符串。我尝试将其转换为 <Buffer>使用Buffer.from(res.data, 'utf-8') ,并将其上传为 Body S3.putObject()的参数.

这将成功将文档上传到 S3,并具有正确的文件大小和页数,但从 S3 下载 PDF 将返回空白文档。

从 Postman 下载文档效果很好,所以我知道问题不在于 res.data从 DocuSign 返回。

SO 上的类似帖子让我认为在尝试将 PDF 转换为 <Buffer> 时遇到编码问题。 。我尝试将编码从 UTF-8 转换为 base64:结果相同,但我不确定是否正确执行。

许多相同的后期解决方案都利用文件流解决方案来转换文档,遗憾的是 Lambda 不允许使用 fs 。因此,为了利用fs ,我尝试直接从客户端应用程序访问 DocuSign API,但 DocuSign 不允许跨源资源共享,因此无法实现。

最后,类似帖子中的解决方案都没有解决如何使用 JavaScript 来执行此操作,全部都是 PHP 和 Python。

完整代码如下:

const downloadEnvelopeDocuments = async ({ envelope_id, account_id, base_uri, token }) => {
    try {

        const url = `${base_uri}/restapi/v2.1/accounts/${account_id}/envelopes/${envelope_id}/documents/combined`
        const res = await axios.get(url, { headers: { Authorization: `Bearer ${token}` }});

        await S3.putObject({
          Bucket: 'targetBucket',
          Key: 'targetDir/docusign-test.pdf',
          Body: Buffer.from(res.data, 'utf8')
        })
        .promise();

    } catch (err) {
        //log error
    }
};

以下是 DocuSign 的完整回复,减去完整的 res.data,因为它的长度远远超过 30,000 个字符(查看超过 200,000 个字符):

{
  status: 200,
  statusText: 'OK',
  headers: {
    'cache-control': 'no-cache',
    'content-length': '167989',
    'content-type': 'application/pdf',
    'x-ratelimit-reset': '1588881600',
    'x-ratelimit-remaining': '998',
    'x-ratelimit-limit': '1000',
    'x-burstlimit-remaining': '498',
    'x-burstlimit-limit': '500',
    'x-docusign-tracetoken': '1da5c492-4709-449e-90fa-c6b31d12b4ac',
    'content-disposition': `file; filename="Test1.pdf"; documentid="combined"; filename*=UTF-8''Test1.pdf`,
    date: 'Thu, 07 May 2020 19:17:50 GMT',
    connection: 'close'
  },
  config: {
    url: 'https://demo.docusign.net/restapi/v2.1/accounts/[REDACTED]/envelopes/[REDACTED]/documents/combined',
    method: 'get',
    headers: {
      Accept: 'application/json, text/plain, */*',
      Authorization: 'Bearer [REDACTED]',
      'User-Agent': 'axios/0.19.2'
    },
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    adapter: [Function: httpAdapter],
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    validateStatus: [Function: validateStatus],
    data: undefined
  },
  request: ClientRequest {
    _events: [Object: null prototype] {
      socket: [Function],
      abort: [Function],
      aborted: [Function],
      error: [Function],
      timeout: [Function],
      prefinish: [Function: requestOnPrefinish]
    },
    _eventsCount: 6,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: false,
    useChunkedEncodingByDefault: false,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    _contentLength: 0,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      _SNICallback: null,
      servername: false,
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 9,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'demo.docusign.net',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [Circular],
      [Symbol(res)]: [TLSWrap],
      [Symbol(asyncId)]: 404,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    connection: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      _SNICallback: null,
      servername: false,
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 9,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'demo.docusign.net',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [Circular],
      [Symbol(res)]: [TLSWrap],
      [Symbol(asyncId)]: 404,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _header: 'GET /restapi/v2.1/accounts/[REDACTED]/envelopes/[REDACTED]/documents/combined HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Authorization: Bearer [REDACTED]\r\n' +
      'User-Agent: axios/0.19.2\r\n' +
      'Host: demo.docusign.net\r\n' +
      'Connection: close\r\n' +
      '\r\n',
    _onPendingData: [Function: noopPendingOutput],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object],
      requests: {},
      sockets: [Object],
      freeSockets: {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'GET',
    insecureHTTPParser: undefined,
    path: '/restapi/v2.1/accounts/[REDACTED]/envelopes/[REDACTED]/documents/combined',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      readable: false,
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      socket: [TLSSocket],
      connection: [TLSSocket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      headers: [Object],
      rawHeaders: [Array],
      trailers: {},
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 200,
      statusMessage: 'OK',
      client: [TLSSocket],
      _consuming: true,
      _dumped: false,
      req: [Circular],
      responseUrl: 'https://demo.docusign.net/restapi/v2.1/accounts/[REDACTED]/envelopes/[REDACTED]/documents/combined',
      redirects: [],
      [Symbol(kCapture)]: false
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    _redirectable: Writable {
      _writableState: [WritableState],
      writable: true,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _options: [Object],
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 0,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function],
      _currentRequest: [Circular],
      _currentUrl: 'https://demo.docusign.net/restapi/v2.1/accounts/[REDACTED]/envelopes/[REDACTED]/documents/combined',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      authorization: [Array],
      'user-agent': [Array],
      host: [Array]
    }
  },
  data: '%PDF-1.5\n' +
    '%����\n' +
    '%Writing objects...\n' +
    '4 0 obj\n' +
    '<<\n' +
    '/Type /Page\n' +
    '/Resources 5 0 R\n' +
    '/Contents [6 0 R 7 0 R 8 0 R ]\n' +
    '/MediaBox [0 0 612 792 ]\n' +
    '/Parent 3 0 R\n' +
    '/StructParents 0\n' +
    '>>\n' +
    'endobj\n' +
    '5 0 obj\n' +
    '<<\n' +
    '/ExtGState <<\n' +
    '/G3 9 0 R\n' +
    '>>\n' +
    '/Font <<\n' +
    '/F4 10 0 R\n' +
    '/F5 11 0 R\n' +
    '>>\n' +
    '/ProcSet [/PDF /Text /ImageB /ImageC /ImageI ]\n' +
    '/XObject <<\n' +
    '/X0 12 0 R\n' +
    '>>\n' +
    '>>\n' +
    'endobj\n' +
    '2 0 obj\n' +
    '<<\n' +
    '/Producer (PDFKit.NET 20.1.200.12352)\n' +
    "/CreationDate (D:20200507121751-07'00')\n" +
    "/ModDate (D:20200507121751-07'00')\n" +
    '/Author ()\n' +
    '/Creator ()\n' +
    '/Keywords <>\n' +
    '/Subject ()\n' +
    '/Title ()\n' +
    '>>\n' +
    'endobj\n' +
    '6 0 obj\n' +
    '<<\n' +
    '/Length 4\n' +
    '>>\n' +
    'stream\n' +
    '\n' +
    ' q \n' +
    'endstream\n' +
    'endobj\n' +
    '7 0 obj\n' +
    '<<\n' +
    '/Filter /FlateDecode\n' +
    '/Length 619\n' +
    '>>\n' +
    'stream\n' +
    'x��Y�j�0\u0010}�W�\u0010Es�HP\u0002M��e�\u001f�&�B\n' +
    'I�\u001f��z�%ʹ��+��k�5\u001ak��stf�\u0006\u0017�q\u0006�K3�/\u000f��\u001d��u��v���}/�^�^��-���\u001e�n����~8�!w��zH\u0010\u001d\u0004�[\u0017wG�|,�!:x��߀��y��{��o���.7��5;`\u001f%�Or��\u0001�\u0004�y\u0018\n' +
    '�\u0019@9��ކ�z�6�\u0006\b^\u0012�2��E�Z�\u0007)�k�\f\u001c�A=a\u0002�yB2&�nB��\u0012\u0003���\u001a��\u0017����\fW\u0002�!P5�\u000f\n' +
    "YEgpX\u001c�\t\u0002a\u0004I)D��Dh\u0006bg��\u0007/��\u0005�\u0018�jH�c��91�P�3!�tȹ1ē�W��ڨr\f�LY�cn�`D��\u0019x� � ^\u000b�0�\u0006�Ⲙ\u0019�\u001a~�pe�\b\u0019�kΰi\tV�j�/3t`k��o�m\fq;� �M٭]P���h���|�z�E<S�Mu��'K\t֢v�Eb��,\u000e�|$k-�?V\u0002\n" +
    `�CD9�OK�b����ן�P'5"�d{�\u0005j���ؗ\u000b�[�\u0017"x\u0018�]�\u001e�H=��Hv\u000f���e�dx��6c_b�Q"\u001d&�%\r��vҤ����,��f���\u0000f����\u001d��~\u000bG]�\u0019����l�h���[��n�,=n���.\u0015��\b:�\u0000�l1��R=[rM��ԛ�-\f��h��\f>�L[�p���]D��4�<-ɞ�g���N����]S�J�JH\u000e���x�k���\u0017W?\u00011Rnk\n` +
    'endstream\n' +
    'endobj\n' +
    '8 0 obj\n' +
    '<<\n' +
    '/Length 17\n' +
    '>>\n' +
    'stream\n' +
    '\n' +
    ' Q  q /X0 Do\n' +
    ' Q \n' +
    'endstream\n' +
    'endobj\n' +
    '9 0 obj\n' +
    '<<\n' +
    '/BM /Normal\n' +
    '/ca 1\n' +
    '>>\n' +
    'endobj\n' +
    '10 0 obj\n' +
    '<<\n' +
    '/BaseFont /ArialMT\n' +
    '/DescendantFonts [13 0 R ]\n' +
    '/Encoding /Identity-H\n' +
    '/Subtype /Type0\n' +
    '/ToUnicode 14 0 R\n' +
    '/Type /Font\n' +
    '>>\n' +
    'endobj\n' +
    '11 0 obj\n' +
    '<<\n' +
    '/BaseFont /Arial-BoldMT\n' +
    '/DescendantFonts [15 0 R ]\n' +
    '/Encoding /Identity-H\n' +
    '/Subtype /Type0\n' +
    '/ToUnicode 16 0 R\n' +
    '/Type /Font\n' +
    '>>\n' +
    'endobj\n' +
    '12 0 obj\n' +
    '<<\n' +
    '/Type /XObject\n' +
    '/Subtype /Form\n' +
    '/FormType 1\n' +
    '/Resources <<\n' +
    '/Properties <<\n' +
    '/MC0 17 0 R\n' +
    '/MC1 18 0 R\n' +
    '/MC2 19 0 R\n' +
    '/MC3 20 0 R\n' +
    '/MC4 21 0 R\n' +
    '/MC5 22 0 R\n' +
    '>>\n' +
    '/Font <<\n' +
    '/Tall_F 23 0 R\n' +
    '/Tall_F0 24 0 R\n' +
    '>>\n' +
    '/XObject <<\n' +
    '/I0 25 0 R\n' +
    '/I1 26 0 R\n' +
    '>>\n' +
    '>>\n' +
    '/BBox [0.00000 0.00000 612.00000 792.00000 ]\n' +
    '/Filter /FlateDecode\n' +
    '/Length 721\n' +
    '>>\n' +
    'stream\n' +
    'x��W�j�0\u0010}�W�\u0007�\u001d�$˂Rh6ii!\u000f[���\u0012\u001c\u001b\u0002\t%\u0017���\u0019I����\u0017�B�k�\u001e�fF�9�#o��nA>\n' +
    '��yH�ly��\u001cn�ŧ����rxT��%�ӳe�8\u001b�\\\u000f��/�jxhR\u0005�y\u0018�4K�M�ny�gKg�~l���b��j�\u001a�%ӎ��Z˪��z/ ���T\u0012ʌ.�x�\u001a��WO��� \u00144\u0016�˛�_�U�\\�I��\u0000`-@7Q3\u0000�\u00018�w���6\u0002�d�E�wtg{�9\u0014"}�\t����}�1�P���FS��o8�*�96�&>�a�T+�,�X\u001d���:��o�\\\u0018k�-9|�\u001f�����I\r�:_+&\\��"Ș����`��i;�C\b����n���q�C��G\u0011� Z\u0006�ȴc$ߑ�1y:�Bl\u001a\u0017�m�sl�w)ߦ�\u0014o�Aqa\u001f� g�C\u000euۣy{�h�\u0011!ڥ�ʣ/(d\u0004�w�<b����\n' +
    '�\n' +
    '1\u0019\u001bc=\u001eی��}5������`��qȓz\u0006\u001d\u000b�)�Y(LB����.���H�P�aacQ�\b�,H\u0010\u001bJ�\u000bK����y�;��*Χ\u0018��x�Q@}\u0016�IJ��OsC\u0014��\u0016�I !\t](b*9Y$����Yv��D:�d�K�1�[�P~�\u001a��\\��ҟ��Y��ڎ+i��;\n' +
    '׎)Rr՝�N\u0002g�\\�.4�ꖗ\u0005��\n' +
    '��Z��&�������:�����$\u0011���|�~�\u0000"��\t��\u00187���ab�\u0004���Т}\u000f��\u0019y6�W���it�r���=� �|SR��R/|N��\u0004����,����xd�0�G+d`v�\u0018���\u000e\u0019�\u0007�؉�f��=�������\u000b�<��\n' +
    'endstream\n' +
    'endobj\n' +
    '13 0 obj\n' +
    '<<\n' +
    '/BaseFont /ArialMT\n' +
    '/CIDSystemInfo <<\n' +
    '/Ordering (Identity)\n' +
    '/Registry (Adobe)\n' +
    '/Supplement 0\n' +
    '>>\n' +
    '/CIDToGIDMap /Identity\n' +
    '/DW 0\n' +
    '/FontDescriptor 27 0 R\n' +
    '/Subtype /CIDFontType2\n' +
    '/Type /Font\n' +
    '/W [0 [750 0 0 277.83203 ] 16 [333.00781 ] 29 [277.83203 ] 38 39 722.16797 44 \n' +
    '[277.83203 ] 49 [722.16797 ] 54 [666.99219 610.83984 ] 68 69 556.15234 70 [500 ] \n' +
    '71 74 556.15234 76 79 222.16797 80 [833.00781 556.15234 556.15234 0 0 333.00781 500 277.83203 556.15234 0 \n' +
    '0 500 ] ]\n' +
    '>>\n' +
    'endobj\n' +
    '14 0 obj\n' +
    '<<\n' +
    '/Filter /FlateDecode\n' +
    '/Length 312\n' +
    '>>\n' +
    'stream\n' +
    'x�]�Mn�0\u0010��>���"\u0002\f�TBH)i$\u0016�QI\u000f\u0000��Z*�2΂��̤�TKF������Dusl��<zw�l��A\u001b�`��N\u0002��\rK\u0004WZ�\u001b�W��eQ(n���ؘabe�y�\u0011Ng�\u0016�9���\u0007\u0016�9\u0005N�\u000b�|�m��j�7�`<�YUq\u0005C�饳��\b<²m�¹��6��9΋\u0005.�\u0013�FN\n' +
    'f�Ip��\u0000+�*^�ª\u0018\u0018��|OU� �:��4��X��JILt$:"�\u0007$Q#e�HiB�\u001d�v\u0005\u00119w�̟��=�sK����-v\u0014]н)�������ed�SJB�,�Ě�s\u0012�Y�[\u0007��\u000eg}����չ0t|i��:gm��3�ɮU��\u0001i��N\n' +
    'endstream\n' +
    'endobj\n' +
    '15 0 obj\n' +
    '<<\n' +
    '/BaseFont /Arial-BoldMT\n' +
    '/CIDSystemInfo <<\n' +
    '/Ordering (Identity)\n' +
    '/Registry (Adobe)\n' +
    '/Supplement 0\n' +
    '>>\n' +
    '/CIDToGIDMap /Identity\n' +
    '/DW 0\n' +
    '/FontDescriptor 28 0 R\n' +
    '/Subtype /CIDFontType2\n' +
    '/Type /Font\n' +
    '/W [0 [750 0 0 277.83203 ] 20 21 556.15234 29 [333.00781 ] 41 [610.83984 ] 53 \n' +
    '[722.16797 ] 70 72 556.15234 76 [277.83203 ] 81 83 610.83984 85 \n' +
    '[389.16016 0 333.00781 ] ]\n' +
    '>>\n' +
    'endobj\n' +
    '16 0 obj\n' +
    '<<\n' +
    '/Filter /FlateDecode\n' +
    '/Length 295\n' +
    '>>\n' +
    'stream\n' +
    'x�]�Mj�0\u0010F�:�,�E�e�I\u0003�\u0010�\u0016��\u000fu{\u0000G\u001a��Z\u0016����+ͤ)T`Ó�O3١=��\u0004����:\f0\u0018�=���+�\u0013��\u0015�\u0000mT�\u0012���;�E�[�ck�I�5@�\u001eO��\u0017�����"{�\u001a��g��<t���s�8�\r���\u0001�C��w/�����ju<7aYE��cq\b\u0005��4j�8�^���\u0019E���@�\u0014W#���;�N���=U��:ϋ�I$�D垨�\u0011�7DeET\u0015Dq3Ѧdz`��\u000eL;���-{ՖiM�9��T�G�5�IvKɮ�\u0004\u001cy�x�����4�[#����C\u001a\u001c5/��X���M.Y��\u0001�\\�l\n' +
    'endstream\n' +
    'endobj\n' +
    '17 0 obj\n' +
    '<<\n' +
    '/Type <50616765>\n' +
    '>>\n' +
    'endobj\n' +
    '18 0 obj\n' +
    '<<\n' +
    '/Type <50616765>\n' +
    '>>\n' +
    'endobj\n' +
    '19 0 obj\n' +
    '<<\n' +
    '/Type <50616765>\n' +
    '>>\n' +
    'endobj\n' +
    '20 0 obj\n' +
    '<<\n' +
    '/Type <50616765>\n' +
    '>>\n' +
    'endobj\n' +
    '21 0 obj\n' +
    '<<\n' +
    '/Type <50616765>\n' +
    '>>\n' +
    'endobj\n' +
    '22 0 obj\n' +
    '<<\n' +
    '/Type <50616765>\n' +
    '>>\n' +
    'endobj\n' +
    '23 0 obj\n' +
    '<<\n' +
    '/Type /Font\n' +
    '/Subtype /Type0\n' +
    '/BaseFont /TCAGDV+ArialMT\n' +
    '/DescendantFonts [<<\n' +
    '/Type /Font\n' +
    '/Subtype /CIDFontType2\n' +
    '/BaseFont /TCAGDV+ArialMT\n' +
    '/W [32 [277 ] 40 [333 333 ] 44 [277 333 277 ] 48 [556 556 556 556 556 556 556 556 556 556 \n' +
    '277 ] 65 [666 666 722 722 666 610 777 ] \n' +
    '73 [277 ] 76 [556 833 722 777 666 ] 82 [722 666 610 722 666 943 ] 89 [666 ] 97 [556 ] \n' +
    '99 [500 556 556 ] 103 [556 556 222 ] 108 [222 833 556 556 556 ] 114 [333 500 277 556 500 722 ] 8226 [350 ] \n' +
    ']\n' +
    '/CIDSystemInfo <<\n' +
    '/Registry (Adobe)\n' +
    '/Ordering (Identity)\n' +
    '/Supplement 1\n' +
    '>>\n' +
    '/FontDescriptor 29 0 R\n' +
    '/CIDToGIDMap 30 0 R\n' +
    '>> ]\n' +
    '/ToUnicode 31 0 R\n' +
    '/Encoding /Identity-H\n' +
    '>>\n' +
    'endobj\n' +
    '24 0 obj\n' +
    '<<\n' +
    '/Type /Font\n' +
    '/Subtype /Type0\n' +
    '/BaseFont /TCAGDW+LucidaConsole\n' +
    '/DescendantFonts [<<\n' +
    '/Type /Font\n' +
    '/Subtype /CIDFontType2\n' +
    '/BaseFont /TCAGDW+LucidaConsole\n' +
    '/W [47 [602 602 ] 50 [602 ] 52 [602 602 602 ] 70 [602 ] 111 [602 ] \n' +
    ']\n' +
    '/CIDSystemInfo <<\n' +
    '/Registry (Adobe)\n' +
    '/Ordering (Identity)\n' +
    '/Supplement 1\n' +
    '>>\n' +
    '/FontDescriptor 32 0 R\n' +
    '/CIDToGIDMap 33 0 R\n' +
    '>> ]\n' +
    '/ToUnicode 34 0 R\n' +
    '/Encoding /Identity-H\n' +
    '>>\n' +
    'endobj\n' +
    '25 0 obj\n' +
    '<<\n' +
    '/Type /XObject\n' +
    '/Subtype /Image\n' +
    '/Filter /FlateDecode\n' +
    '/Width 549\n' +
    '/Height 234\n' +
    '/BitsPerComponent 8\n' +
    '/Length 8735\n' +
    '/ColorSpace [/Indexed /DeviceRGB 255 35 0 R ]\n' +
    '/Mask [251 251 ]\n' +
    '>>\n' +
    'stream\n' +
    `x��]�v\u001bG�n��h��P�ˇ��������<��\u0002�d3�\t��R�̑#F{\u0016\u001bL��(�\u000b0�"h�I3!\u001fB��J�a@v����Su�\u001b@w�\u0000U\u001fut�Bu�޺u��LHHHHHHHHHHHHHHHHHH�>\\g\f\u0007\u001dTq��)��Wm����cU�\u001b�v��~,\u0013��M��cT\b����_���^\u0013�[��Q��P&��k�H�'��,��\u0017��uWDR�\u001e�$�˄5\u0011p�v�d�\u0017��T�+ۇ�It+�R&�\t�\u001cX���\n` +
    "7�ȓ���U��t\u0002M$�OI�4�\u0017N\u0015gL(4\u0006#�//\u0004I�6�:I�\u0015?f���q��}�HNS`\u0017�\u0013ET'I�dm���5�B���K�3�Z����\u001c�Й����mJ⴩�P��\f\n" +
    '���L{�\u0004�&qB���T�N2#+�d<`�\u001f�]�Ի\u000bL�\f8K�H��\n' +
    '\r��@\u0011�"�p�D2\u0013�S�\u0014��(��\u001f`�u��P?*Ӑ��\u000b��"\'���\u0013f¶\u0001�<s�і�8.����������`L�\b�\\e\u00040Of\r��H9�O0��m���k���<�\u0010��\u0015J�\u0019&X��M�\u001b����\'�\u000et���0��tņ�,9�C�I�v\u0019\'��z
{}
���������\u0016\u001fW��+la\u0001w=�)�|(�JNy�6]>Q"ANB�=7�љ�I\u000ef80͍fC\n' +
    '�)�\u0012�����?�~\u001c�a8���;������<��=���ۇ��|�;"��\ruX \u0017&�ߌ���\u001b\u0018f��9<e�ֈ\u001bM;\u001e��\u0014�\f�?f��\u0007o �i�)��J��7�a�q튐�\u001bZ�.�\u0006K��\u001a2��=�M���\u0016S���\u0005K����\u0015�W,(�I�?U�E�61_�\u0002��\u001c�\u0012����\u0014\u0017�\tp��߱\u0001�*�A\u0006[�G��w��&�-�$Ex:�\'R��ɏP�;x���2f��jz\r���?K0���b�m���S�:5\u000fLf��ֳ�C�>[X7��Dp����{��Y�B�Ħ��cR��"\u000e��.U�I�R��|\t-�kG8;�\u0013`\u0004�y��\u0000�iѣ%����䓛\u001da��7�!�ٟ���\u0007}��(��I\u0004w\u001b�$�Z�Z��\u001fgX�!/,�V�q\u0012��H�+(mv\u0019\'�eXUD\u001c�F��R���U�\u001f�r�$س�UwEG��\u0000j\u001co\b9 �us��\r{���\u0005�\u0010׬8��3��{��.$:�+"�\'q�\u0010a��OFڔ���\u0013\u000bUB�����([B�g��\\i\u0014T�8���Ov�\u0014�s��$;�\u000e6�\u0007Z\u001cT"8R�d�.\u0011\toQt��q\u0017�K\u0010grM�Q\u0014 c\u0016�F�y�"�2Ou�S&\b�e�E�X7�Z7_�u�`,��Pm��{�(\'��XMI�~`.\u0007D\u0012߻���\u0000�dZ���L�Ꝃ�F�F��I�]�9���j�85�]!�����X7��*\\\u0001)\u0001�\u0010f�\u001d�P���\u0016\r�?\u0018�I\u001e�O�\u0012�yk]�N�zO�[\u001cj\u000e���v��A�\f�\u0019\u0016w�;�U(�.��}�HH\u0007u�\u0019a\u0007PY��5�[�\u0018�L\'�i�l�w�2:7D.�$=Z�m��jv_ڌ�%��6�]\u0014�s\u0012t�r;a��y&��4�����ۣ3X�P-3�g����h���5L�\u0004���\'~�\u000e�w]ڌ�ɺ�K��\b��n�4\u0019��Y���\u0005)�l��D�%qL\u0019���\u001c9ےX����\u00041�}!�0��\u0016�d�f�\u000eW0)�\u0012\'����p>\u00110�v�I2ڷ*�QG\u0015\b��)�fJf$�\u001a>�O\u0007�\u0017���an��)�\u0001���\u00138\ta^\u0018\u0014eJCW\u0018��L�nh��ՇN��\u000b\u00158ڷ\u000e���jp��\u00040`�Kݍ왔۷;l��\u001c�l\u0000�n�,o�\f�H<��a5�=B�G�w�\u001b�Q䥝E�v�\u0013�D\u001f��\u0016\t\u0010\u0006B\u0013��LN\u0017B\u0005�N�ޭ��0\u0001az\b� ��oڻ���`u��a{��Ak\u0019�F9(N��\u001d�\u0006\u0017�6��I�vcfԍ:�\u0011\u001c�`�C��H:�\'�\u000e\u0001����)���\u0000�1��M�sp�\n' +
    '\u0019ܣ4�\u0004��T�F?(�$O�AK���\u000b�\n' +
    `\u001b�\u0018'9��H�|$�$�!x�=�3�D �b�_�X\u000b0��\u0010nT]�'��\u0019������=\u0002��3�\u001b��y�$\u000b=9�yw����^�4�]����A���\fN��7�3�u+�X��뿼��*�β]v��P��~:�\u0014��\u001dl\tl\fFJ��K�Ą\u0018u�f�&�\u0007A��/7\u0004��w7��o\u0002Gv�\u0011.\r�ɱ9�'��;�H\u000e��:-\u001f?X��\u0006����v�FJ\u0013��_~\u0015\u0000\u001f�F�\f�ɴ�����Z\u001f�e��\f�G�����]&t�Ksv"1��8N̑��\u0015�\t����+\u0013\u0012�0;{I�$�qb��o˄�\u0018\u000eu�s�6\t\u0015\u0018�㜏}k/�\u0011z���LH���\\;�\f��8\n` +
    '}�w�LH��\\E��ք\n' +
    '���?R&$Dq�,��:��-�D$\t\u0015�7��~-\u0013\u0012�8T*�^WG�\u0013\u001e\u0005�t\b����Oh\u0002sak�$\t\u00158ԧ)\u0012�$T ���Z\u001c����u�P�_�5�I�$T ���Z�Y��$T�X7)0-�\u0002I�$��X7�H\u0012*����Z$q�P��w�P�C\u001d㚈$�\u0002�տI�$T@���\'I�¡~eg�$\t\u00150�$�$\t\u00158�/�L�$�\u0002�����P��{���1� �I�\f�\u0016^��Zߘ�"\'ɳA�m}��l�u/\u001d҇�Z�\u0005\u001e���e�z(���喡�ȴ���=]��&��u\'��\u001c�l��:v����\f�����En\u0016�}�]x�צ�\u0015��8fё�+��\'\u001d�HC�ۦԵ\u001bO\u0002c��|\u0010��\'�\u0017�4�=+;Ń.�(��Ip0\u001fDC�g�P\t���Y��c�\u0014�C���\u00168I>-�$=�b�t2ĚF\u0016v�\u001b\u0012d0��s�]h+2M�O��9��\u001c�\u000f�A\'U�R\u0007��٠�\u0012�H�+�\u000bm�$\u0019�G>~(���Y�Azvo�9�Vn\u0017~���I��6��!\\%Ӭ\u0003N����\u0018��(�\u000b�\u0005|�9I�Db\u0007�\u0001��A\u0007���\u0012��Ēy�z���Uy�s�q@$\u000f�O�u�IPظ>�\u001d�\u0012ɶ���\u0013|�#�\u0006@#�\u0007�$9��5\u0014daw��p�]�m��kGq%*���8�$k\u001d�T\u0005�\u0017F�\u001b���V�:����\rq��\u001f����-h��0��\u0006h�t�[+{\r�\u0013O2E")\u001e��\u00007k^��Q�\u0000\u0019I��Eލ\r�\u001c:Ƶ1�\u0018Y:��X����qk0��r��\u0013+9���\u0006���uV�\u000e�ٻ�}\u001b:V\u0019_ϓ\u000e�\u0019\f�����R\u0006H\u0017&�c?�\u0014$�v��{\\\u000bd$j�E�C�~m0���q��_��\u000e6�QN�MԲ:Z��7+`�h#���.��\u0005Պ\u001a\u00018�\u0018[;߈�5�R"iE܌Qܨe��Mb�:���\u0011�ܑ2���K\u001e\b�b#���{7M9I���p_DZl\u001d�\u0014�%i^|a�\u0016Q[�\u001d�@�l#�ju��Į��qc��0��+"\u0019�F$��G��\u000b�0�\u0003\u0012\u0014�p����I�\u0010\u0007�\u0018�C\n' +
    "6j'�;�H\u000b\u0016��*ݫ���k\u0014\u001b�ge\u0018�k3Nb8�\u0004Xe$�\u0004l�.�\n" +
    "n\f4�֚܋)H��f��������^�،�X�\r34��$�H�\u0016��n�3׉�\u0016�t3Rmu�\u0013|��R�!����9\t��.�d�^馡\u0010H�9MaS\u001cke�s7�\u0014W����2d\u000f6Nc\u0017:�\u0010Jo\\�QS�n²�����\u0002\u0006��XL����!���$���`�Xr�;��G\u000b�2�'\u000e\n" +
    'oN$V5�eI��E1]c��ĶXa�iA2Dۯ��ė�\u0011�8ƕg� \u0006�j�褥����}\u000b4Ҽt��\u001b�\u0017��\u0014�th��\u0019�}�e���B辯�܈=n�%���ߍ���,G*z�ٹ\u001b�%q,�R�֚��i;k\u001dԛI�҂HG�U\u0000�\u0014�<\u001f�\u000f\u001e�\f�r�J,�\u00155�/�������\u001e���s7\u0019r\u00123C9\u001bB�1PR�\u001b�h�4Wx����n\t\u0003�C\\��\b{�(���������C\t��I\f�\u001f�q#;(�*�V����S\u0007�\u001b��1��\t\t��@Oi5\u000b\u0000�>FʚN���]�p�t\u000e)��jm\u0003�9��[Ѹ\u0011c/�x\u0017�K�-u\u001a�O���\u0011oѸ!�g�PTbWyݢ\u000e��1�\u000f\n' +
    '���\t5�b<�=e\u0003օ��\u0011y�<\u0010�\u001a�DBJ\u001a�D��\u0003\n' +
    '��\u0003 �^��ÒZ�8*���a<�拿b�)T8\u00075��W1�)CGT��C�u��h�Aw!��7��k�}7��t�\b�7\u00034\\�[\u0005�\u0005au␒U\ti-���)�\u0006��\u000f\u001cm���Oҳ:e��C�"l��{_���y�&O�7gپ�˾B"���eh��DUK\u0006-�+\u0011�ւ\u000fƟ�A̅e�i\u0012����F\u000e�*�t}(\u0006Y\u0014\u0005��+o\u001a�p�=k�;���N����\u0005��\u0012\u0011��V�#c��\u000eRh3`\u0004\u001ae\u001a\u0012�\u000b>MÊ\u00117\u000bD\u000eM\rc�8\'\u0019�31\u0013j0q%\u0012*BE5�j-������kp���Sڶ�/o��V�w\n' +
    '�\u0017\u0011R\u00140\u0012Z�\\J\\\u0013l�j����NDN\u0012n�0NB�\u0004�\rE�ה��z�u�3����$� �q#�c�����,�K��I��\n' +
    '��*\t�"k��3"2�0\rc)\\���Z���8�<$rİ��nt[cqc\u001a��VKΤ�c3^��K\u0000ߩ\u0019P�<��\u0018���\t���4�\u0014;\u0006\u0014BL3��&�F�2h�1\u0012|J$�iUAk�q<�nҀ\u0013I�H�d\u001a��*N�3����x�8�i�ͮD#�(�\b��:aJ�;������c�KR������j�A�;��]v�&�7\u0006���T�w�@��)*���\u0002\u0012��\u0017�1\u0017z\u001bO}n�\u00
...

最佳答案

作为原始 pdf 的替代方案,您还可以将响应数据转换为 base64。只需包含此 header “Content-Transfer-Encoding”:“base64”即可​​。

关于node.js - 从 Lambda 上传的 AWS S3 返回空白 PDF (Node.js),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61666776/

相关文章:

php - 使用 PHP 将数据从 PDF 导入数据库

amazon-web-services - 是否可以将数据从 Redshift 传输到 Elasticsearch?

javascript - 在 Node.JS/express 全局访问 Firebase

node.js - PostgreSQL 的 Sequelize.js 事务问题

python - 使用python从格式化的PDF中提取文本

php - 在谷歌文档查看器中显示 AWS 文件

amazon-web-services - AWS S3 读取是否保证返回新创建的对象?

javascript - 然后在 Javascript 中使用外部变量

javascript - 为什么 webpack 无法从我的 React Web 应用程序中找到任何模块?

pdf - 在 Excel 中使用 VBA 打开 PDF