如何使用 Vapor 响应图像?
How to respond with an image using Vapor?
我只想有一个控制器动作,基本上与直接通过 Public/
文件夹访问图像相同。不同之处在于路线可以是您想要的任何东西,返回的图像将是在控制器函数内部确定的图像。但是如何创建适当的响应呢?
我的方法是这样的:
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)
}
}
但在我看来我过于复杂了,是吗?
另外两种方法:
使用Leaf部署镜像的路由:
route.get("/my/random/route") {
request -> Future<View> in
return try request.view().render("image", ["imgname":"image.png"])
}
与 image.leaf 包含:
<img src="#(imgname)">
重定向到 Public
中的原始位置:
route.get("/my/random/route") {
request -> Response in
return request.redirect(to: "/image.png")
}
但是如何创建正确的响应?
直接创建一个Response
并设置MediaType
:request.makeResponse(data, as: MediaType.png)
示例:
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
}
}
}
我只想有一个控制器动作,基本上与直接通过 Public/
文件夹访问图像相同。不同之处在于路线可以是您想要的任何东西,返回的图像将是在控制器函数内部确定的图像。但是如何创建适当的响应呢?
我的方法是这样的:
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)
}
}
但在我看来我过于复杂了,是吗?
另外两种方法:
使用Leaf部署镜像的路由:
route.get("/my/random/route") { request -> Future<View> in return try request.view().render("image", ["imgname":"image.png"]) }
与 image.leaf 包含:
<img src="#(imgname)">
重定向到
Public
中的原始位置:route.get("/my/random/route") { request -> Response in return request.redirect(to: "/image.png") }
但是如何创建正确的响应?
直接创建一个Response
并设置MediaType
:request.makeResponse(data, as: MediaType.png)
示例:
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
}
}
}