Cherrypy 服务的路径为 404

404 for path served by Cherrypy

对于三个简单的应用程序:让我们使用与 8080 不同的端口:

cherrypy.config.update({'server.socket_host': '127.0.0.1',
                    'server.socket_port': 28130
                   })

让我们设置三个应用程序:

fusionConf = { '/fusion':{}} mobileConf = { r"/mobile_to_fusion":{}} adminConf = { '/admin':{}}

cherrypy.tree.mount(fusionListener, r"/fusion",fusionConf) cherrypy.tree.mount(mobileListener, r"/mobile_to_fusion",mobileConf) cherrypy.tree.mount(adminListener, r"/admin",adminConf) #

cherrypy.engine.start() cherrypy.engine.block()

我们可以在正确的端口 运行 上看到它:

$netstat -an | grep 28130
tcp4       0      0  127.0.0.1.28130        *.*                    LISTEN

应用程序日志记录同意:

CherryPy Checker:
The application mounted at '/fusion' has config entries that start with its script name: '/fusion'

CherryPy Checker:
The application mounted at '/mobile_to_fusion' has config entries that start with its script name: '/mobile_to_fusion'

CherryPy Checker:
The application mounted at '/admin' has config entries that start with its script name: '/admin'

但是在访问 url 时:http://localhost:28130/admin - 没有找到?

404 Not Found
The path '/admin' was not found.

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/cherrypy/_cprequest.py", line 638, in respond
    self._do_respond(path_info)
  File "/usr/local/lib/python3.8/site-packages/cherrypy/_cprequest.py", line 697, in _do_respond
    response.body = self.handler()
  File "/usr/local/lib/python3.8/site-packages/cherrypy/lib/encoding.py", line 219, in __call__
    self.body = self.oldhandler(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/cherrypy/_cperror.py", line 416, in __call__
    raise self
cherrypy._cperror.NotFound: (404, "The path '/admin' was not found.")
Powered by CherryPy 18.5.0

为什么 Cherrypy 找不到路径?

AdminListener class 安装在 /admin 下, AdminListener 没有 defaultindex 方法能够在 /admin 下安装一个 AdminListener 的实例并期望它能工作。例如,对于您当前的实施,/admin/admin 应该有效。

您可以:

  1. AdminListener中定义def default(self)def index(self)(替换admin方法)或
  2. '' 下安装 AdminListener 的实例。与 cherrypy.tree.mount(adminListener, "",adminConf) 一样,这会产生将 adminConf 应用于所有子应用程序的副作用,因此我认为正确的方法是选项 1.

例如,对于选项 1:

  class AdminListener(object):
      @cherrypy.expose
      def index(self, param=None):
          return "Hello from Admin"

或者

  class AdminListener(object):
      @cherrypy.expose
      def default(self, param=None):
          return "Hello from Admin"

主要区别在于index方法不会像位置参数一样消耗url片段,例如/admin/one将不起作用,但/admin/?param=one将与indexdefault(注意第二个 / 很重要)。

default 方法就像一个 包罗万象的 替代方法,它将为应用程序挂载点下的任何未定义路径调用。