简体   繁体   English

如何使用 Vapor 提供静态文件?

[英]How to serve static files using Vapor?

I'm trying to write server side application using Swift and Vapor framework.我正在尝试使用 Swift 和 Vapor 框架编写服务器端应用程序。 However, I can't figure out, how to serve static files using Vapor.但是,我不知道如何使用 Vapor 提供静态文件。 It's not enough to just move them to the Public or Resources directory.仅仅将它们移动到PublicResources目录是不够的。

How can I do that?我该怎么做?

UPD.更新。 I performed steps which Tanner Nelson suggested but it still doesn't work.我执行了 Tanner Nelson 建议的步骤,但它仍然不起作用。

What I tried so far:到目前为止我尝试过的:

  1. vapor build and vapor run (using Vapor Toolbox v0.6.1). vapor buildvapor run (使用 Vapor Toolbox v0.6.1)。

  2. ./build/debug/App from root directory (which contains Package.swift ). ./build/debug/App从根目录(包含Package.swift )。

  3. Run in Xcode 8 beta after editing scheme as Tanner Nelson suggested.按照 Tanner Nelson 的建议,在编辑方案后在 Xcode 8 beta 中运行。

In all this cases I get error {"error":true,"message":"Page not found"}在所有这些情况下,我都会收到错误{"error":true,"message":"Page not found"}

I have file vapor_logo.png inside a Public folder and also the same file inside Public/images/ folder.我在Public文件夹中有文件vapor_logo.png ,在Public/images/文件夹中有相同的文件。 I try to request it and it fails.我尝试请求它但它失败了。 Requests that I made: http://localhost:8080/image/vapor_logo.png and http://localhost:8080/vapor_logo.png .我提出的请求: http://localhost:8080/image/vapor_logo.pnghttp://localhost:8080/vapor_logo.png However, other routes work fine.但是,其他路线工作正常。

UPD 2. Well, that was all my mistakes. UPD 2.好吧,那都是我的错误。 First, file that I think was called vapor_logo.png , actually was called vapor-logo.png .首先,我认为文件名为vapor_logo.png ,实际上被称为vapor-logo.png Second, case matters when you make a request.其次,当您提出请求时,案例很重要。 I also tried to request file with name IMG_8235.JPG but write file extension as jpg , so got an error.我还尝试请求名称为IMG_8235.JPG文件,但将文件扩展名写入jpg ,因此出现错误。

So, just to recap: if you experience the same problem as me, follow the Tanner Nelson's answer and make sure that name of requested file exactly matches name of file on disk.所以,回顾一下:如果您遇到与我相同的问题,请按照 Tanner Nelson 的回答并确保所请求文件的名称与磁盘上的文件名称完全匹配。

Vapor folder structure from Docs :来自Docs 的Vapor 文件夹结构:

VaporApp
├── Package.swift
├── Resources
│   ├── Views
│   │   └── hello.leaf
├── Public
│   ├── images (images resources)
│   ├── styles (css resources)
└── Sources
    └── ...

Any files in the Public folder will be served by default if no routes have been registered that conflict with the file name.如果没有注册与文件名冲突的路由,则默认情况下将提供Public文件夹中的任何文件。

For example, if you have a file Public/foo.png and the following main.swift file:例如,如果您有一个文件Public/foo.png和以下main.swift文件:

import Vapor

let drop = Droplet()

drop.get("welcome") { request in
    return "Hello, world"
}

drop.serve()

A request to localhost/welcome would return "Hello, world" and a request to localhost/foo.png would return foo.png .localhost/welcome请求将返回"Hello, world" ,对localhost/foo.png的请求将返回foo.png

If this is not working properly, it's likely that your working directory is not configured properly.如果这不能正常工作,很可能是您的工作目录没有正确配置。 This can happen if you are running your project from Xcode or you are running it from the command line from a folder that is not the root directory of the project.如果您从 Xcode 运行您的项目,或者您从不是项目根目录的文件夹中从命令行运行它,就会发生这种情况。

To fix Xcode, go to Schemes > App > Edit Scheme > Run > Options > Working Directory > [x] Use Custom Working Directory and make sure the directory is set to the root of your project (where the Package.swift resides).要修复 Xcode,请转到Schemes > App > Edit Scheme > Run > Options > Working Directory > [x] Use Custom Working Directory ,并确保该目录设置为项目的根目录(Package.swift 所在的位置)。

Xcode 工作目录

To fix when running from the command line, make sure you are running the application from the root directory.要在从命令行运行时进行修复,请确保从根目录运行应用程序。 ie, the run command should look something like .build/debug/App since the .build folder is located in the root directory.即,运行命令应该类似于.build/debug/App因为.build文件夹位于根目录中。

对我来说,这是在configure.swift取消注释这一行:

middlewares.use(FileMiddleware.self) // Serves files from `Public` directory

In addition to the answer with FileMiddleware , sometimes one needs to serve a specific file instead of the whole Public directory, that's where using request.fileio.streamFile could help:除了FileMiddleware的答案FileMiddleware ,有时需要提供特定文件而不是整个Public目录,这就是使用request.fileio.streamFile可以提供帮助的地方:

app.get("file") { (request: Request) in
  // stream the file
  request.eventLoop.makeSucceededFuture(
    request.fileio.streamFile(at: "/your/filepath")
  )
}

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

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