Google App Engine和404错误

时间:2008-10-10 00:51:00

标签: python google-app-engine http-status-code-404

我使用其他地方找到的提示在GAE上设置了静态网站,但无法弄清楚如何返回404错误。我的app.yaml文件看起来像

- url: (.*)/
  static_files: static\1/index.html
  upload: static/index.html

- url: /
  static_dir: static

将所有静态html / jpg文件存储在静态目录下。以上适用于存在的文件,但如果不存在,则返回空长文件。答案可能是编写一个python脚本来返回404错误,但是如何设置为现有的静态文件提供服务但是为不存在的文件运行脚本呢?

以下是在开发应用程序服务器上获取不存在的文件(nosuch.html)的日志:

ERROR    2008-11-25 20:08:34,084 dev_appserver.py] Error encountered reading file "/usr/home/ctuffli/www/tufflinet/static/nosuch.html":
[Errno 2] No such file or directory: '/usr/home/ctuffli/www/tufflinet/static/nosuch.html'
INFO     2008-11-25 20:08:34,088 dev_appserver.py] "GET /nosuch.html HTTP/1.1" 404 -

9 个答案:

答案 0 :(得分:37)

您需要注册一个catch-all脚本处理程序。在app.yaml:

的末尾添加此内容
- url: /.*
  script: main.py

在main.py中,您需要输入以下代码:

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class NotFoundPageHandler(webapp.RequestHandler):
    def get(self):
        self.error(404)
        self.response.out.write('<Your 404 error html page>')

application = webapp.WSGIApplication([('/.*', NotFoundPageHandler)],
                                     debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()

<Your 404 error html page>替换为有意义的内容。或者更好地使用模板,您可以阅读如何执行该操作here

如果您在设置时遇到问题,请与我们联系。

答案 1 :(得分:27)

谷歌应用引擎现在有Custom Error Responses

所以你现在可以在你的app.yaml中添加一个error_handlers部分,如下例所示:

error_handlers:

- file: default_error.html

- error_code: over_quota
    file: over_quota.html

答案 2 :(得分:5)

在不需要任何CPU周期的情况下执行此操作的一种非常简单的方法是将此处理程序放在app.yaml的底部

- url: /.*
    static_files: views/404.html
    upload: views/404.html

然后,您可以在视图目录中放置一个静态404.html文件。不需要python处理程序。你的app.yaml中没有处理的任何内容都会触及。

答案 3 :(得分:4)

您可以创建一个函数来处理任何状态代码的错误。你的情况是404,定义一个这样的函数:

def Handle404(request, response, exception):
     response.out.write("Your error message") 
     response.set_status(404)`

您可以在response.out.write函数中传递任何内容 - HTML /纯文本/模板。现在,在app声明后添加以下声明。

app.error_handlers[404] = Handle404

这对我有用。

答案 4 :(得分:3)

webapp2提供了可用于提供自定义错误页面的error_handlers字典。 示例如下:

def handle_404(request, response, exception):
    logging.warn(str(exception))
    response.set_status(404)
    h = YourAppBaseHandler(request, response)
    h.render_template('notfound')

def handle_500(request, response, exception):
    logging.error(str(exception))
    response.set_status(500)
    h = YourAppBaseHandler(request, response)
    h.render_template('servererror')

app = webapp2.WSGIApplication([
    webapp2.Route('/', MainHandler, name='home')
    ], debug=True)
app.error_handlers[404] = handle_404
app.error_handlers[500] = handle_500

webapp2的文档页面提供了更多详细信息:http://webapp-improved.appspot.com/guide/app.html#error-handlers

答案 5 :(得分:2)

对于与映射不匹配的任何内容,dev_appserver已经返回404响应,或者与映射匹配但不存在。 404响应本身没有正文,但它仍然是404:

$ wget -O - http://127.0.0.1:8080/foo
--2010-10-28 10:54:51--  http://127.0.0.1:8080/foo
Connecting to 127.0.0.1:8080... connected.
HTTP request sent, awaiting response... 404 
2010-10-28 10:54:51 ERROR 404: (no description).

$ wget -O - http://127.0.0.1:8080/foo/
--2010-10-28 10:54:54--  http://127.0.0.1:8080/foo/
Connecting to 127.0.0.1:8080... connected.
HTTP request sent, awaiting response... 404 
2010-10-28 10:54:54 ERROR 404: (no description).

如果您想返回更加用户友好的错误页面,请按照jonmiddleton的建议并指定自定义404页面。

答案 6 :(得分:2)

我已经回顾了上面给出的所有答案,并在最后使用以下内容作为最通用的404解决方案:

app.yaml

的末尾添加此链接
- url: /(.*) 
  script: 404.app

并使用以下内容创建404.py

import webapp2
from google.appengine.ext.webapp import template

class NotFound(webapp2.RequestHandler):
  def get(self):
    self.error(404)
    self.response.out.write(template.render('404.html', {}))

app = webapp2.WSGIApplication([
    ('/.*', NotFound)
], debug=True)

这将显示带有404错误代码的404.html文件的内容。

此解决方案的优点是简单,行为正确且灵活,因为它允许使用静态404.html文件作为错误页面内容。

我还想警告上面提出的一些解决方案。

  • Custom Error Responses不能使用404错误
  • 也不要使用静态文件,因为它们会返回200而不是404错误。这可能会引起很多头痛。

答案 7 :(得分:0)

我无法评论jonmiddleton的答案,但自定义错误响应是针对App引擎特定错误的外观。 我没有看到指定自定义404页面的方法。

Django让你specify一个。

答案 8 :(得分:0)

我的方法是在我作为最后一个处理的catch all处理程序中处理404和永久重定向。当我重新设计并重新命名/替换网址时,这非常有用:

app = webapp2.WSGIApplication([
    ...
    ...
    ('/.*', ErrorsHandler)
], debug=True)


class ErrorsHandler(webapp2.RequestHandler):
    def get(self):
        p = self.request.path_qs
        if p in ['/index.html', 'resources-that-I-removed']:  
            return self.redirect('/and-substituted-with-this', permanent=True)
        else: 
            self.error(404)
            template = jinja_environment.get_template('404.html')
            context =  {
                'page_title': '404',
            }
            self.response.out.write(template.render(context))