mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 18:42:23 +08:00

* [assetserver] Add support for HTTP Middlewares * [dev] Disable frontend DevServer if no Assets has been defined and inform user * [dev] Consistent WebSocket behaviour in dev and prod mode for assets handler and middleware In prod mode we can't support WebSockets so make sure the assets handler and middleware never see WebSockets in dev mode. * [templates] Migrate to new AssetServer option * [docs] Add assetserver.Options to the reference
145 lines
3.5 KiB
Plaintext
145 lines
3.5 KiB
Plaintext
# Dynamic Assets
|
|
|
|
If you want to load or generate assets for your frontend dynamically, you can achieve that using the
|
|
[AssetsHandler](../reference/options#assetshandler) option. The AssetsHandler is a generic `http.Handler` which will
|
|
be called for any non GET request on the assets server and for GET requests which can not be served from the
|
|
bundled assets because the file is not found.
|
|
|
|
By installing a custom AssetsHandler, you can serve your own assets using a custom asset server.
|
|
|
|
## Example
|
|
|
|
In our example project, we will create a simple assets handler which will load files off disk:
|
|
|
|
```go title=main.go {16-35,49}
|
|
package main
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"github.com/wailsapp/wails/v2"
|
|
"github.com/wailsapp/wails/v2/pkg/options"
|
|
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
//go:embed all:frontend/dist
|
|
var assets embed.FS
|
|
|
|
type FileLoader struct {
|
|
http.Handler
|
|
}
|
|
|
|
func NewFileLoader() *FileLoader {
|
|
return &FileLoader{}
|
|
}
|
|
|
|
func (h *FileLoader) ServeHTTP(res http.ResponseWriter, req *http.Request) {
|
|
var err error
|
|
requestedFilename := strings.TrimPrefix(req.URL.Path, "/")
|
|
println("Requesting file:", requestedFilename)
|
|
fileData, err := os.ReadFile(requestedFilename)
|
|
if err != nil {
|
|
res.WriteHeader(http.StatusBadRequest)
|
|
res.Write([]byte(fmt.Sprintf("Could not load file %s", requestedFilename)))
|
|
}
|
|
|
|
res.Write(fileData)
|
|
}
|
|
|
|
func main() {
|
|
// Create an instance of the app structure
|
|
app := NewApp()
|
|
|
|
// Create application with options
|
|
err := wails.Run(&options.App{
|
|
Title: "helloworld",
|
|
Width: 1024,
|
|
Height: 768,
|
|
AssetServer: &assetserver.Options{
|
|
Assets: assets,
|
|
Handler: NewFileLoader(),
|
|
},
|
|
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 255},
|
|
OnStartup: app.startup,
|
|
Bind: []interface{}{
|
|
app,
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
println("Error:", err)
|
|
}
|
|
}
|
|
```
|
|
|
|
When we run the application in dev mode using `wails dev`, we will see the following output:
|
|
|
|
```
|
|
DEB | [ExternalAssetHandler] Loading 'http://localhost:3001/favicon.ico'
|
|
DEB | [ExternalAssetHandler] Loading 'http://localhost:3001/favicon.ico' failed, using AssetHandler
|
|
Requesting file: favicon.ico
|
|
```
|
|
|
|
As you can see, the assets handler is called when the default assets server is unable to serve
|
|
the `favicon.ico` file.
|
|
|
|
If you right click the main application and select "inspect" to bring up the devtools, you can test
|
|
this feature out by typing the following into the console:
|
|
|
|
```
|
|
let response = await fetch('does-not-exist.txt');
|
|
```
|
|
|
|
This will generate an error in the devtools. We can see that the error is what we expect, returned by
|
|
our custom assets handler:
|
|
|
|
```mdx-code-block
|
|
<p className="text--center">
|
|
<img
|
|
src={require("@site/static/img/assetshandler-does-not-exist.webp").default}
|
|
/>
|
|
</p>
|
|
```
|
|
|
|
However, if we request `go.mod`, we will see the following output:
|
|
|
|
```mdx-code-block
|
|
<p className="text--center">
|
|
<img src={require("@site/static/img/assetshandler-go-mod.webp").default} />
|
|
</p>
|
|
```
|
|
|
|
This technique can be used to load images directly into the page. If we updated our default vanilla template and
|
|
replaced the logo image:
|
|
|
|
```html
|
|
<img id="logo" class="logo" />
|
|
```
|
|
|
|
with:
|
|
|
|
```html
|
|
<img src="build/appicon.png" style="width: 300px" />
|
|
```
|
|
|
|
Then we would see the following:
|
|
|
|
```mdx-code-block
|
|
<p className="text--center">
|
|
<img
|
|
src={require("@site/static/img/assetshandler-image.webp").default}
|
|
style={{ width: "75%" }}
|
|
/>
|
|
</p>
|
|
```
|
|
|
|
:::warning
|
|
|
|
Exposing your filesystem in this way is a security risk. It is recommended that you properly manage access
|
|
to your filesystem.
|
|
|
|
:::
|