简体   繁体   English

如何使用Vapor响应图像?

[英]How to respond with an image using Vapor?

I just want to have a controller action that is basically doing the same as accessing an image directly through the Public/ folder. 我只想要一个控制器动作,基本上与直接通过Public/文件夹访问图像相同。 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? 但在我看来,我太复杂了,是吗?

But how to create a proper response? 但是如何创造适当的反应呢?

Directly create a Response and set the MediaType : request.makeResponse(data, as: MediaType.png) 直接创建一个Response并设置MediaTyperequest.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
        }
    }
}

Two additional approaches: 另外两种方法:

  1. A route using Leaf to deploy the image: 使用Leaf部署映像的路由:

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

With image.leaf containing: 使用image.leaf包含:

<img src="#(imgname)">
  1. A re-direct to the original location in Public : 重定向到Public的原始位置:

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

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

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