Загрузка изображения из Angular 8 через AWS API Gateway, Lambda на S3 - PullRequest
0 голосов
/ 06 июля 2019

У меня это в основном работает, к сожалению, файл, который начинается как .png, становится мусором к тому времени, когда он на S3.

На угловой стороне я выполняю загрузку с:

  public uploadAsset(file: File, pointer: string):
    { name: string, url: string, isImg: boolean } {

    const url: string = this.API_URL + '/posts' + pointer + '/assets' ;

    // this will be the our resulting map
    const status: { name: string, url: string, isImg: boolean } = {name: file.name, url: url + '/' + file.name, isImg: true};

    // create a new multipart-form for the file
    const formData: FormData = new FormData();
    formData.append('file', file, file.name);

    // create a http-post request and pass the form
    // tell it to report the upload progress

    const req = new HttpRequest('POST', url, formData, {
      params: new HttpParams().set('fileName', file.name),
      reportProgress: true
    });

    // create a new progress-subject for every file
    const progress = new Subject<number>();

    // send the http-request and subscribe for progress-updates
    this.http.request(req).subscribe(event => {
      if (event.type === HttpEventType.UploadProgress) {

        // calculate the progress percentage
        const percentDone = Math.round(100 * event.loaded / event.total);

        // pass the percentage into the progress-stream
        console.log(progress);
        progress.next(percentDone);
      } else if (event instanceof HttpResponse) {

        // Close the progress-stream if we get an answer form the API
        // The upload is complete
        progress.complete();
      }
    });

    return status;
  }

Лямбда, которая его обрабатывает, имеет следующий код:

export const handler = async (event: any = {}) : Promise <any> => {
    console.log(event);
    const corsHeaders = {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Credentials': true,
    };
    try {
        const method = event.httpMethod;

        if (method === "GET") {

            // GET handling left out for brevity
        }
        if (method === "POST") {

            const path: string[] = event.path.split('/');
            const s3Location = path[1] + '/' + path[2] + '/' + path[3];

            const filename = event.queryStringParameters.fileName;
            console.log(s3Location);
            // Return error if we do not have a name
            if (!s3Location) {
                return {
                    statusCode: 400, headers: corsHeaders,
                    body: "name missing"
                };
            }

            let base64data = Buffer.from(event.body, 'base64');

            await S3.putObject({
                ACL: "public-read",
                Bucket: bucketName,
                Key: s3Location + '/' + filename,
                Body: base64data,
                ContentType: contentTypeFromFile(filename)
            }).promise();

            return {
                statusCode: 200, headers: corsHeaders,
                body: JSON.stringify(event.queryStringParameters),
                isBase64Encoded: false
            };
        }

        if (method === "DELETE") {

            // DELETE handling left out for brevity
        }

        // We got something besides a GET, POST, or DELETE
        return {
            statusCode: 400, headers: corsHeaders,
            body: "We only accept GET, POST, and DELETE, not " + method
        };
    } catch(error) {
        const body = error.stack || JSON.stringify(error, null, 2);
        return {
            statusCode: 400, headers: corsHeaders,
            body: body
        }
    }
};

function assetFileNameFromEvent(event: any) {
    const path: string[] = event.path.split('/');
    return path[1] + '/' + path[2] + '/' + path[3] + '/' + path[4];
}

function contentTypeFromFile(locationKey: string): string {
    const extension = locationKey.split('.')[1];

    let contentType = 'image/';

    switch(extension) {
        case 'jpg': {
            contentType += 'jpeg';
            break;
        }
        case 'jpeg': {
            contentType += 'jpeg';
            break;
        }
        case 'gif': {
            contentType += 'gif';
            break;
        }
        case 'png': {
            contentType += 'png';
            break;
        }
        default: {
            contentType += '*';
            break;
        }
    }
    return contentType;
}

Запрос определенно поступает на эту лямбду, потому что я вижу вывод консоли в Cloudwatch, а именно: console.log(event); output:

2019-07-01T05:46:34.301Z    45035f0b-6c87-48dc-a83d-e02c4b4ff925    { resource: '/posts/{id}/assets',
path: '/posts/the-4-constraints-of-project-management/assets',
httpMethod: 'POST',
headers: 
{ Accept: 'application/json, text/plain, */*',
'accept-encoding': 'gzip, deflate, br',
'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8',
'CloudFront-Forwarded-Proto': 'https',
'CloudFront-Is-Desktop-Viewer': 'true',
'CloudFront-Is-Mobile-Viewer': 'false',
'CloudFront-Is-SmartTV-Viewer': 'false',
'CloudFront-Is-Tablet-Viewer': 'false',
'CloudFront-Viewer-Country': 'AU',
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7AbJvvIOfZxOpNVc',
Host: 's4lr6s31m3.execute-api.ap-southeast-2.amazonaws.com',
origin: 'http://localhost:4200',
Referer: 'http://localhost:4200/post-edit/the-4-constraints-of-project-management',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
Via: '2.0 d06686d3facabf043210ce048fc0afb2.cloudfront.net (CloudFront)',
'X-Amz-Cf-Id': 'sD6er2yXk2xTHwLio2dLusmxVlW4aBtL8XXfihnoc1cDdsPD95T7Ng==',
'X-Amzn-Trace-Id': 'Root=1-5d199e39-3fbc1d9861cda5c9e6016d19',
'X-Forwarded-For': '220.237.138.198, 54.239.202.94',
'X-Forwarded-Port': '443',
'X-Forwarded-Proto': 'https' },
multiValueHeaders: 
{ Accept: [ 'application/json, text/plain, */*' ],
'accept-encoding': [ 'gzip, deflate, br' ],
'Accept-Language': [ 'en-GB,en-US;q=0.9,en;q=0.8' ],
'CloudFront-Forwarded-Proto': [ 'https' ],
'CloudFront-Is-Desktop-Viewer': [ 'true' ],
'CloudFront-Is-Mobile-Viewer': [ 'false' ],
'CloudFront-Is-SmartTV-Viewer': [ 'false' ],
'CloudFront-Is-Tablet-Viewer': [ 'false' ],
'CloudFront-Viewer-Country': [ 'AU' ],
'content-type': 
[ 'multipart/form-data; boundary=----WebKitFormBoundary7AbJvvIOfZxOpNVc' ],
Host: [ 's4lr6s31m3.execute-api.ap-southeast-2.amazonaws.com' ],
origin: [ 'http://localhost:4200' ],
Referer: 
[ 'http://localhost:4200/post-edit/the-4-constraints-of-project-management' ],
'User-Agent': 
[ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' ],
Via: 
[ '2.0 d06686d3facabf043210ce048fc0afb2.cloudfront.net (CloudFront)' ],
'X-Amz-Cf-Id': [ 'sD6er2yXk2xTHwLio2dLusmxVlW4aBtL8XXfihnoc1cDdsPD95T7Ng==' ],
'X-Amzn-Trace-Id': [ 'Root=1-5d199e39-3fbc1d9861cda5c9e6016d19' ],
'X-Forwarded-For': [ '220.237.138.198, 54.239.202.94' ],
'X-Forwarded-Port': [ '443' ],
'X-Forwarded-Proto': [ 'https' ] },
queryStringParameters: { fileName: '4constraints.png' },
multiValueQueryStringParameters: { fileName: [ '4constraints.png' ] },
pathParameters: { id: 'the-4-constraints-of-project-management' },
stageVariables: null,
requestContext: 
{ resourceId: '1l0n12',
resourcePath: '/posts/{id}/assets',
httpMethod: 'POST',
extendedRequestId: 'cIWpCEhaSwMF6MA=',
requestTime: '01/Jul/2019:05:46:33 +0000',
path: '/prod/posts/the-4-constraints-of-project-management/assets',
accountId: '499908792600',
protocol: 'HTTP/1.1',
stage: 'prod',
domainPrefix: 's4lr6s31m3',
requestTimeEpoch: 1561959993894,
requestId: '95662d4b-9bc3-11e9-8a59-31b56e75ceeb',
identity: 
{ cognitoIdentityPoolId: null,
accountId: null,
cognitoIdentityId: null,
caller: null,
sourceIp: '220.237.138.198',
principalOrgId: null,
accessKey: null,
cognitoAuthenticationType: null,
cognitoAuthenticationProvider: null,
userArn: null,
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
user: null },
domainName: 's4lr6s31m3.execute-api.ap-southeast-2.amazonaws.com',
apiId: 's4lr6s31m3' },
body: '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',
isBase64Encoded: true }

Тело даже выглядит закодированным в base64, что, как я читал в другом месте, является хорошей вещью. Однако, когда я смотрю в S3 или выполняю GET, я получаю искаженный файл (без изображения). Хотя размер файла одинаков (или, по крайней мере, очень похож).

Я надеюсь, что мне не хватает чего-то маленького, возможно, какого-то простого преобразования, которое я должен сделать. Может кто-нибудь сказать мне, что это может быть?

...