J'ai configuré un site Web statique sur GAE à l'aide d'indices trouvés ailleurs, mais je ne vois pas comment renvoyer une erreur 404. Mon fichier app.yaml ressemble à
- url: (.*)/
static_files: static\1/index.html
upload: static/index.html
- url: /
static_dir: static
avec tous les fichiers html/jpg statiques stockés dans le répertoire static. Ce qui précède fonctionne pour les fichiers existants, mais retourne un fichier de longueur NULL s'ils ne le font pas. La réponse est probablement d'écrire un script python pour renvoyer une erreur 404, mais comment configurer les choses pour servir les fichiers statiques existants tout en exécutant le script pour les fichiers qui n'en ont pas?
Voici le journal de récupération d'un fichier non existant (nosuch.html) sur le serveur d'applications de développement:
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 -
Vous devez enregistrer un gestionnaire de script fourre-tout. Ajoutez ceci à la fin de votre app.yaml:
- url: /.*
script: main.py
Dans main.py, vous devrez mettre ce code:
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 __== "__main__":
main()
Remplacez <Your 404 error html page>
par quelque chose de significatif. Ou mieux utilisez un modèle, vous pouvez lire comment faire cela ici .
S'il vous plaît laissez-moi savoir si vous avez des problèmes pour le mettre en place.
google App Engine a maintenant Réponses d'erreur personnalisées
afin que vous puissiez maintenant ajouter une section error_handlers à votre app.yaml, comme dans cet exemple:
error_handlers:
- file: default_error.html
- error_code: over_quota
file: over_quota.html
Une façon beaucoup plus simple de faire cela sans nécessiter de cycle de processeur consiste à placer ce gestionnaire au bas de votre application.yaml
- url: /.*
static_files: views/404.html
upload: views/404.html
Cela vous permet ensuite de placer un fichier statique 404.html dans votre répertoire de vues. Pas besoin d'un gestionnaire de python. Tout ce qui n'est pas déjà traité dans votre application.yaml le fera déjà.
Vous pouvez créer une fonction pour gérer vos erreurs pour n’importe quel code d’état. Vous êtes en train d'être 404, définissez une fonction comme ceci:
def Handle404(request, response, exception):
response.out.write("Your error message")
response.set_status(404)`
Vous pouvez transmettre n'importe quoi - HTML/texte brut/modèles dans la fonction response.out.write
. Maintenant, ajoutez la déclaration suivante après votre déclaration app
.
app.error_handlers[404] = Handle404
Cela a fonctionné pour moi.
webapp2
fournit le dictionnaire error_handlers
que vous pouvez utiliser pour afficher des pages d'erreur personnalisées. Exemple ci-dessous:
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
Plus de détails sont disponibles sur les pages de documentation de webapp2
: http://webapp-improved.appspot.com/guide/app.html#error-handlers
J'ai examiné toutes les réponses données ci-dessus et utilisé les éléments suivants à la fin comme solution 404 la plus universelle:
Ajouter ce lien à la fin de app.yaml
- url: /(.*)
script: 404.app
et créez 404.py
avec le contenu suivant
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)
Cela affichera le contenu du fichier 404.html
avec le code d'erreur 404.
L'avantage de cette solution est la simplicité, l'exactitude du comportement et la flexibilité, car elle permet d'utiliser un fichier 404.html
statique comme contenu de page d'erreur.
Je tiens également à mettre en garde contre certaines des solutions suggérées ci-dessus.
Custom Error Responses
ne fonctionne pas avec l'erreur 404Le serveur dev_appserver renvoie déjà 404 réponses pour tout ce qui ne correspond pas au mappage, ou correspond au mappage mais n'existe pas. La réponse 404 elle-même n'a pas de corps, mais reste une 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).
Si vous souhaitez retourner une page d'erreur plus conviviale, suivez les conseils de jonmiddleton et spécifiez une page 404 personnalisée.
Je ne peux pas commenter la réponse de jonmiddleton, mais les réponses d'erreur personnalisées concernent les erreurs propres au moteur d'applications. Je ne vois pas de moyen de spécifier une page 404 personnalisée.
Django vous laisse spécifier un cependant.
Mon approche consiste à gérer à la fois les redirections 404 et permanentes dans un gestionnaire catch all que je mets en dernier. Ceci est utile lorsque je modifie l'application et que je renomme/substitue des 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))