How to upload images from the browser to Amazon S3 using Vapor and Leaf?

久未见 提交于 2019-12-11 12:40:00

问题


I have set up AWS S3 bucket and I'm able to upload files there using Vapor 3 and Postman (PUT -request and with headers: ["x-amz-acl" : "public-read"]) but I would like to do that from the browser (I'm using leaf).

So how can I upload image files from the browser? I'm new with HTML, AWS S3 and Vapor.

I'm using:

  • Vapor 3
  • AWS S3
  • Leaf package
  • S3 package
  • VaporExt package

I followed this tutorial to set up everything (except the get request and the bucket policies): https://fivedottwelve.com/blog/using-amazon-s3-with-vapor/

Get the url:

func preparePresignedUrl(request: Request) throws -> String {

    let baseUrl = awsConfig.url
    let imagePath = awsConfig.imagePath
    let newFilename = UUID().uuidString + ".png"


    guard var url = URL(string: baseUrl) else {
        throw Abort(.internalServerError)
    }
    url.appendPathComponent(imagePath)
    url.appendPathComponent(newFilename)

    let headers = ["x-amz-acl" : "public-read"]

    let s3 = try request.makeS3Signer()
    let result = try s3.presignedURL(for: .PUT, url: url, expiration: Expiration.hour, headers: headers)

    guard let presignedUrl = result?.absoluteString else {
        throw Abort(.internalServerError)
    }

    return presignedUrl
}

A route handler:

func ImagesHandler(_ req: Request) throws -> Future<View> {

    let presignedUrl = try preparePresignedUrl(request: req)
    let context = PostImageContext(title: "Add Image", url: presignedUrl)
    return try req.view().render("addImage", context)
}

A context that contains the data for the Leaf variables:

struct PostImageContext: Encodable {
    let title : String
    let url : String
}

The Leaf file (addImage.leaf):

#set("content") {

    <h1>#(title)</h1>

    <form method="PUT", action="#(url)", enctype="multipart/form-data">

    <div class="form-group">
    <label>
        Choose Image
    </label>
    <input type="file"
    class="form-control-file"/>
    </div>

    <button type="submit" class="btn btn-primary">
        Upload
    </button>   
    </form>
}

#embed("base")

And it returns an error:

"NoSuchKeyThe specified key does not exist"

I learnt that the only valid values for the method attribute are get and post what means that is invalid HTML and will be treated like , i.e. send a GET request (explains the error I got).

How can I work around this using Vapor? Thank you for your help!

来源:https://stackoverflow.com/questions/56372209/how-to-upload-images-from-the-browser-to-amazon-s3-using-vapor-and-leaf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!