AWS POST requires exactly one fileupload per request

158 阅读2分钟

TypeError: source.on is not a function
POST requires exactly one fileupload per request

项目中使用 Node request 上传文件到 AWS 服务,总是出现 POST requires exactly one fileupload per request 或 TypeError: source.on is not a function 错误。

<Error><Code>InvalidArgument</Code><Message>POST requires exactly one file upload per request.</Message><Key></Key><BucketName></BucketName><Resource>/wwae</Resource><RequestId>3L137</RequestId><HostId>3L137</HostId></Error>

因为 AWS 服务上传的接口需要一些在获取上传链接的时候返回的参数,把这些参数正确写入才能正确上传。上传成功后 httpResponse.statusCode 的状态返回为 204.

代码实现如下

let fs = require('fs')
let request = require('request')

// result 为 get_upload_url 请求返回的结果
// console.log(result) 
let fields = result[0].fields
let url = result[0].url
let formData = {
  key: fields.key,
  'x-amz-algorithm': fields['x-amz-algorithm'],
  'x-amz-signature': fields['x-amz-signature'],
  'x-amz-date': fields['x-amz-date'],
  policy: fields.policy,
  'x-amz-credential': fields['x-amz-credential'],
  file: fs.createReadStream(__dirname + '/data/1.jpg')
}
// console.log(formData)
request.post({ url: url, formData: formData }, function optionalCallback (err, httpResponse, body) {
  if (err) {
    return console.error('upload failed:', err)
  }
  console.log(httpResponse.statusCode)
  console.log(httpResponse.statusMessage)
  console.log('Upload successful! Server responded with:', body)
})

get_upload_url 接口返回结果

[ { url: 'https://minio.xxxx.com/xxxx',
    fields:
     { key: 'data/115392487245051422.jpg',
       'x-amz-algorithm': 'AWS4-HMAC-SHA256',
       'x-amz-signature':
        '45b4abed8fefd23e1c271076934070346efce9548267b5d5703f393b28fc23bb',
       'x-amz-date': '20181011T090524Z',
       policy:
        'eyJjb25kaXRpb25zIjogW3siYnVja2V0IjogInd3YWUifSwgeyJrZXkiOiAiZGF0YS8xMTUzOTI0ODcyNDUwNTE0MjIuanBnIn0sIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwgeyJ4LWFtei1jcmVkZW50aWFsIjogInNnLWFpLzIwMTgxMDExL3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVlc3QifSwgeyJ4LWFtei1kYXRlIjogIjIwMTgxMDExVDA5MDUyNFoifV0sICJleHBpcmF0aW9uIjogIjIwMTgtMTAtMTFUMTE6MDU6MjRaIn0=',
       'x-amz-credential': 'sg-ai/20181011/us-east-1/s3/aws4_request' } },
  'data/115392487245051422.jpg' ]

formData 输出如下

{ key: 'data/1.jpg',
  'x-amz-algorithm': 'AWS4-HMAC-SHA256',
  'x-amz-signature':
   '397538760dcd1b4b8d1cc883f86faf7d636e9c4f384e9348a8258b76219954e0',
  'x-amz-date': '20181011T090352Z',
  policy:
   'eyJjb25kaXRpb25zIjogW3siYnVja2V0IjogInd3YWUifSwgeyJrZXkiOiAiZGF0YS8xLmpwZyJ9LCB7IngtYW16LWFsZ29yaXRobSI6ICJBV1M0LUhNQUMtU0hBMjU2In0sIHsieC1hbXotY3JlZGVudGlhbCI6ICJzZy1haS8yMDE4MTAxMS91cy1lYXN0LTEvczMvYXdzNF9yZXF1ZXN0In0sIHsieC1hbXotZGF0ZSI6ICIyMDE4MTAxMVQwOTAzNTJaIn1dLCAiZXhwaXJhdGlvbiI6ICIyMDE4LTEwLTExVDExOjAzOjUyWiJ9',
  'x-amz-credential': 'sg-ai/20181011/us-east-1/s3/aws4_request',
  file:
   ReadStream {
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 65536,
        buffer: BufferList { length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: null,
        ended: false,
        endEmitted: false,
        reading: false,
        sync: true,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        emitClose: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: true,
     _events: { end: [Function] },
     _eventsCount: 1,
     _maxListeners: undefined,
     path:
      '/home/w/my/project/WeWoAppEngine/src/frontend/test/stress/data/1.jpg',
     fd: null,
     flags: 'r',
     mode: 438,
     start: undefined,
     end: Infinity,
     autoClose: true,
     pos: undefined,
     bytesRead: 0,
     closed: false } }