Вопрос

Я настроил статический веб-сайт на 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 -
Это было полезно?

Решение

Вам необходимо зарегистрировать обработчик скриптов для всех целей. Добавьте это в конец вашего 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> чем-то значимым. Или лучше использовать шаблон, вы можете прочитать, как это сделать здесь .

Пожалуйста, дайте мне знать, если у вас есть проблемы с настройкой.

Другие советы

Значительно более простой способ сделать это, не требуя циклов ЦП, - разместить этот обработчик внизу вашего app.yaml

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

Затем вы можете поместить статический файл 404.html в каталог представлений. Нет необходимости в обработчике Python. Все, что не обработано в вашем app.yaml, уже попадет в это.

Вы можете создать функцию для обработки ваших ошибок для любого из кодов состояния.Ваш случай равен 404, определите функцию следующим образом:

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

Вы можете передать что угодно - HTML / обычный текст / шаблоны в response.out.write функция.Теперь добавьте следующее объявление после вашего app декларация.

app.error_handlers[404] = Handle404

У меня это сработало.

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.

Я рассмотрел все приведенные выше ответы и использовал следующее в конце как наиболее универсальное решение 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.html файл с кодом ошибки 404.

Преимуществом этого решения является простота, корректность поведения и гибкость, поскольку оно позволяет использовать статический 404.html файл как содержимое страницы с ошибкой.

Я также хочу предостеречь от некоторых решений, предложенных выше.

  • Custom Error Responses не работает с ошибкой 404
  • Также не используйте статические файлы, так как они вернут ошибку 200 вместо ошибки 404.Это может вызвать сильную головную боль в будущем.

Я не могу комментировать ответ jonmiddleton, но пользовательские сообщения об ошибках предназначены для ошибок, специфичных для механизма приложений, по их виду. Я не вижу способа указать пользовательскую страницу 404.

Django позволяет вам указать один из них.

Мой подход состоит в том, чтобы обрабатывать как 404, так и постоянные перенаправления в обработчике catch all, который я установил как последний. Это полезно, когда я изменяю дизайн, приложение и переименовываю / заменяю URL:

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))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top