简体   繁体   English

Angular 4 Web应用程序:如何使用Amazon S3返回公共链接?

[英]Web Application with Angular 4: how to return a public link with Amazon S3?

I'm developing a web application with Angular 4 using TypeScript language. 我正在使用TypeScript语言使用Angular 4开发Web应用程序。 The backend of this application is based on AWS. 该应用程序的后端基于AWS。

Unfortunately I don't have a great knowledge of TypeScript (JavaScript) methods to call up procedures that interacting with AWS services, but what I have to do is very simple. 不幸的是,我不太了解TypeScript(JavaScript)方法来调用与AWS服务交互的过程,但是我要做的很简单。 The question is: if I load a file on a Amazon S3 Bucket (an image), how do I get the link (like as string) that let me use it to show the image on the web page? 问题是:如果我将文件加载到Amazon S3存储桶(图像)上,如何获得链接(如字符串),让我用它来在网页上显示图像?

I would like to create an internal TypeScript method for my application, without make public the link using the command on S3. 我想为我的应用程序创建一个内部TypeScript方法,而不使用S3上的命令公开链接。

This method must have a reference to the bucket S3 (folder name and file name) and must return a public link as a string accessible to anyone. 此方法必须引用存储区S3(文件夹名称和文件名),并且必须以字符串形式返回任何人都可以访问的公共链接。 Anyone who knows how to do this thing can tell me? 有谁知道该怎么做才能告诉我吗?

Here are files from my project that you can use. 这是我的项目中可以使用的文件。 If you need any explanation, feel free to ask, but I guess that with comments only, you could understand it : 如果您需要任何解释,请随时提出,但是我想仅凭评论您就可以理解:

ANGULAR SERVICE 语言服务

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
// environment useful for the nodeJS API endpoint
import { environment } from '../../../environments/environment';

@Injectable()
export class S3UploadService {

  constructor(private http: Http, private session: SessionManagerService) { }

  /**
   * Gets a signed request from AWS
   * @param file The file to upload
   */
  getSignedRequest(file: File): Observable<{ signedRequest: string, url: string }> {
    // Randomly generated name : 8 random, user ID, timestamp, extension. Should ensure uniqueness.
    let name = Math.random().toString(36).substr(2, 8)
      + '-' + Parse.User.current().id + '-'
      + new Date().getTime().toString() + '.'
      + file.name.split('.').pop();
    return this.http.get(`${environment.remoteUrl}sign-s3?file-name=${name}&file-type=${file.type.toLowerCase()}`)
      .map(data => data.json())
      .catch(err => Observable.throw(err));
  }

  /**
   * Uploads a file on Amazon
   * @param file The file to upload
   * @param signedRequest The signed request returned by the getSignedRequest method
   * @param url The URL of the file on the AWS
   */
  uploadFile(file: File, signedRequest: string, url: string): Observable<{ url: string }> {
    // WARNING : No json() function here, Amazon doesn't send json responses.
    return this.http.put(signedRequest, file)
      .map(data => {
        // get rid of the signature
        data.url = data.url.split('?')[0];
        return data;
      })
      .catch(err => Observable.throw(err));
  }
}

NODEJS ENDPOINT NODEJS端点

// Gets a signed request from amazon.
app.get('/sign-s3', function(req, res) {
  const s3 = new aws.S3();
  const fileName = req.query['file-name'];
  const fileType = req.query['file-type'];
  const s3Params = {
    Bucket: S3_BUCKET,
    Key: fileName,
    Expires: 60,
    ContentType: fileType,
    ACL: 'public-read'
  };
  s3.getSignedUrl('putObject', s3Params, function(err, data) {
    if (err) {
      console.log('Error occured : \n' + err);
      return res.status(500).send(JSON.stringify({ message: 'Internal Server Error' }));
    }
    const returnData = {
      signedRequest: data,
      url: 'https://' + S3_BUCKET + '.s3.amazonaws.com/' + fileName
    };
    res.write(JSON.stringify(returnData));
    res.end();
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM