使用自定义路由器时出现问题的Wails资产处理程序

huangapple go评论117阅读模式
英文:

Issue using wails asset handler using custom router

问题

我正在尝试使用自定义多路复用器(multiplexer)与Wails资产处理程序一起使用,但是当尝试获取任何内容时,我始终得到index.html页面。我已经在多路复用器的ServeHTTP函数的顶部添加了一个打印语句,但是这只在程序开始时获取favicon.ico时被调用一次。

我有以下的主文件:

package main

import (
	"embed"
	"fmt"

	"github.com/Nigel2392/router/v3"
	"github.com/Nigel2392/router/v3/request"
	"github.com/wailsapp/wails/v2"
	"github.com/wailsapp/wails/v2/pkg/options"
	"github.com/wailsapp/wails/v2/pkg/options/assetserver"
)

var ROUTER *router.Router = router.NewRouter(true)

func init() {
	ROUTER.Get("/about", func(r *request.Request) {
		fmt.Println("About")
		r.WriteString("About")
	})
}

//go:embed all:frontend/dist
var assets embed.FS

func main() {
	// Create an instance of the app structure
	app := NewApp()

	// Create application with options
	err := wails.Run(&options.App{
		Title:  "new",
		Width:  1024,
		Height: 768,
		AssetServer: &assetserver.Options{
			Assets:  assets,
			Handler: ROUTER,
		},
		BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
		OnStartup:        app.startup,
		Bind: []interface{}{
			app,
		},
	})

	if err != nil {
		println("Error:", err.Error())
	}
}

我可以在终端中看到以下输出:

DEB | [ExternalAssetHandler] Loading 'http://localhost:3000/favicon.ico'
DEB | [ExternalAssetHandler] Loading 'http://localhost:3000/favicon.ico' failed, using AssetHandler

# 在serveHTTP函数的顶部的打印语句,
# 打印请求的路径和可用的路由路径。
Path:  /favicon.ico
GET /about ->

DEB | [ExternalAssetHandler] Loading 'http://localhost:3000/about'


要在浏览器中开发并从Javascript调用绑定的Go方法,请导航到:http://localhost:34115
DEB | [ExternalAssetHandler] Loading 'http://localhost:3000/@vite/client'
DEB | [ExternalAssetHandler] Loading 'http://localhost:3000/node_modules/vite/dist/client/env.mjs'
DEB | [ExternalAssetHandler] Loading 'http://localhost:3000/about'
DEB | [ExternalAssetHandler] Loading 'http://localhost:3000/@vite/client'
DEB | [ExternalAssetHandler] Loading 'http://localhost:3000/node_modules/vite/dist/client/env.mjs'
DEB | [ExternalAssetHandler] Loading 'http://localhost:3000/about'

当尝试获取关于页面进行测试时,如wails的AssetServer文档中所述,我获取到了索引页面:

let resp = await fetch("/about")
undefined
await resp.text()
'<!DOCTYPE html>\n<html lang="en">\n<head>\n  <script type="module" src="/@vite/client"></script>\n\n    <meta charset="UTF-8"/>\n    <meta content="width=device-width, initial-scale=1.0" name="viewport"/>\n    <meta name="wails-options" content="noautoinject" />\n    <script src="/wails/ipc.js"></script>\n    <script src="/wails/runtime.js"></script>\n    <title>new</title>\n</head>\n<body>\n    <h1>Index!</h1>\n    <a href="/about">Go To About!</a>\n</body>\n</html>\n'

为什么serveHTTP函数没有被调用?

英文:

I am trying to use a custom multiplexer with the Wails asset handler, however when trying to fetch anything I keep getting the index.html page. I have added a print statement at the top of the ServeHTTP function of the multiplexer, but this only gets called once, when fetching favicon.ico at the start of the program.

I have the following main file:

package main

import (
	&quot;embed&quot;
	&quot;fmt&quot;

	&quot;github.com/Nigel2392/router/v3&quot;
	&quot;github.com/Nigel2392/router/v3/request&quot;
	&quot;github.com/wailsapp/wails/v2&quot;
	&quot;github.com/wailsapp/wails/v2/pkg/options&quot;
	&quot;github.com/wailsapp/wails/v2/pkg/options/assetserver&quot;
)

var ROUTER *router.Router = router.NewRouter(true)

func init() {
	ROUTER.Get(&quot;/about&quot;, func(r *request.Request) {
		fmt.Println(&quot;About&quot;)
		r.WriteString(&quot;About&quot;)
	})
}

//go:embed all:frontend/dist
var assets embed.FS

func main() {
	// Create an instance of the app structure
	app := NewApp()

	// Create application with options
	err := wails.Run(&amp;options.App{
		Title:  &quot;new&quot;,
		Width:  1024,
		Height: 768,
		AssetServer: &amp;assetserver.Options{
			Assets:  assets,
			Handler: ROUTER,
		},
		BackgroundColour: &amp;options.RGBA{R: 27, G: 38, B: 54, A: 1},
		OnStartup:        app.startup,
		Bind: []interface{}{
			app,
		},
	})

	if err != nil {
		println(&quot;Error:&quot;, err.Error())
	}
}

I can see the following output in the terminal:

DEB | [ExternalAssetHandler] Loading &#39;http://localhost:3000/favicon.ico&#39;
DEB | [ExternalAssetHandler] Loading &#39;http://localhost:3000/favicon.ico&#39; failed, using AssetHandler

# Print statement at the top of the serveHTTP function, 
# prints the requested path, and the available router paths.
Path:  /favicon.ico
GET /about -&gt;

DEB | [ExternalAssetHandler] Loading &#39;http://localhost:3000/about&#39;


To develop in the browser and call your bound Go methods from Javascript, navigate to: http://localhost:34115
DEB | [ExternalAssetHandler] Loading &#39;http://localhost:3000/@vite/client&#39;
DEB | [ExternalAssetHandler] Loading &#39;http://localhost:3000/node_modules/vite/dist/client/env.mjs&#39;
DEB | [ExternalAssetHandler] Loading &#39;http://localhost:3000/about&#39;
DEB | [ExternalAssetHandler] Loading &#39;http://localhost:3000/@vite/client&#39;
DEB | [ExternalAssetHandler] Loading &#39;http://localhost:3000/node_modules/vite/dist/client/env.mjs&#39;
DEB | [ExternalAssetHandler] Loading &#39;http://localhost:3000/about&#39;

When trying to fetch the about page for testing, as explained in the wails AssetServer documentation, I retrieve the index page:

let resp = await fetch(&quot;/about&quot;)
undefined
await resp.text()
&#39;&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n&lt;head&gt;\n  \x3Cscript type=&quot;module&quot; src=&quot;/@vite/client&quot;&gt;\x3C/script&gt;\n\n    &lt;meta charset=&quot;UTF-8&quot;/&gt;\n    &lt;meta content=&quot;width=device-width, initial-scale=1.0&quot; name=&quot;viewport&quot;/&gt;\n    &lt;meta name=&quot;wails-options&quot; content=&quot;noautoinject&quot; /&gt;\n    \x3Cscript src=&quot;/wails/ipc.js&quot;&gt;\x3C/script&gt;\n    \x3Cscript src=&quot;/wails/runtime.js&quot;&gt;\x3C/script&gt;\n    &lt;title&gt;new&lt;/title&gt;\n&lt;/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;Index!&lt;/h1&gt;\n    &lt;a href=&quot;/about&quot;&gt;Go To About!&lt;/a&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n&#39;

Why isn't the serveHTTP function being called?

答案1

得分: 1

日志显示使用了ExternalAssetHandler。这意味着使用了外部前端开发服务器。所有的资源请求都会首先转发到外部前端开发服务器。只有当外部前端开发服务器返回404405状态码时,才会使用assetserver.Options中指定的处理程序。现在,大多数用于单页应用程序的前端开发服务器会为非资源请求提供index.html。这就是你看到这种行为的原因。

一种解决方法是配置外部前端开发服务器来绕过请求。对于Vite,修改配置文件添加类似以下内容:

export default defineConfig({
  server: {
    proxy: {
      '/about': {
        bypass: function () {
          // 返回false以产生请求的404错误。
          return false;
        },
      },
      // 或者对于所有以"/api/"开头的请求
      '/api/': {
        bypass: function () {
          return false;
        },
      },
    },
  },
});

但我建议不要这样做。因为资源处理程序,顾名思义,是用于提供动态资源的。而Wails有自己的方式来调用绑定的Go方法。你应该尝试一下。

参考资料:

英文:

The log shows that an ExternalAssetHandler is used. That implies that an external frontend dev server is used. And all the asset requests are forwarded to the external frontend dev server first. Only when the external frontend dev server responses with a 404 or 405 status code, the handler specified in assetserver.Options will be used. Nowadays, most frontdend dev server for SPA serves index.html for non-asset requests. That's why you see the behavior.

A workaround is to configure the external frontend dev server to bypass the request. For Vite, modify the configuration file to add something like this:

export default defineConfig({
  server: {
    proxy: {
      &#39;/about&#39;: {
        bypass: function () {
          // Return false to produce a 404 error for the request.
          return false;
        },
      },
      // or for all the requests that start with &quot;/api/&quot;
      &#39;/api/&#39;: {
        bypass: function () {
          return false;
        },
      },
    },
  },
});

But I would recommend not to do this. Because an asset handler, as its name implies, it's for serving dynamic assets. And wails has its own way for calling bound Go methods. You should give it a try.

References:

huangapple
  • 本文由 发表于 2023年4月11日 03:40:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75980176.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定