How to respond with an image using Vapor?

杀马特。学长 韩版系。学妹 提交于 2019-12-22 09:56:39

问题


I just want to have a controller action that is basically doing the same as accessing an image directly through the Public/ folder. The difference is that the route can be whatever you want and the returned image will be the one that is determined inside of the controller function. But how to create a proper response?

My approach looks like this:

import Vapor

final class ImageController {
    func read(_ req: Request) throws -> Future<Data> {
        let directory = DirectoryConfig.detect()
        let promise = req.eventLoop.newPromise(Data.self)
        req.eventLoop.execute {
            do {
                let data = try Data(contentsOf: URL(fileURLWithPath: directory.workDir)
                    .appendingPathComponent("Public", isDirectory: true)
                    .appendingPathComponent("image.png"))
                promise.succeed(result: data)
            } catch {
                promise.fail(error: error)
            }
        }
        return promise.futureResult
//        try req.content.encode(data, as: .png)
    }
}

But it seems to me I'm overcomplicating it, do I?


回答1:


Two additional approaches:

  1. A route using Leaf to deploy the image:

    route.get("/my/random/route") {
         request -> Future<View> in
         return try request.view().render("image", ["imgname":"image.png"])
    }
    

With image.leaf containing:

<img src="#(imgname)">
  1. A re-direct to the original location in Public:

    route.get("/my/random/route") {
        request -> Response in
        return request.redirect(to: "/image.png")
    }
    



回答2:


But how to create a proper response?

Directly create a Response and set the MediaType: request.makeResponse(data, as: MediaType.png)

Example:

struct ImageController: RouteCollection {
    func boot(router: Router) throws {
        let imageRoutes = router.grouped("images")
        // GET /images/get-test-image
        imageRoutes.get("get-test-image", use: getTestImage)    
    }

    func getTestImage(_ request: Request) throws -> Response {
        // add controller code here 
        // to determine which image is returned
        let filePath = "/path/to/image18.png"
        let fileUrl = URL(fileURLWithPath: filePath)

        do {
            let data = try Data(contentsOf: fileUrl)
            // makeResponse(body: LosslessHTTPBodyRepresentable, as: MediaType)
            let response: Response = request.makeResponse(data, as: MediaType.png)
            return response
        } catch {
            let response: Response = request.makeResponse("image not available")
            return response
        }
    }
}


来源:https://stackoverflow.com/questions/51975381/how-to-respond-with-an-image-using-vapor

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