405 для Google App Engine. Метод POST не разрешен для добавления этого ресурса в Boilerplate.

Я новичок в движке приложения и работаю над добавлением простой функции чата в шаблон (https://github.com/coto/gae-boilerplate). Приложение чата отлично работает само по себе, но когда я пытаюсь добавить его в шаблон, я получаю ошибку метода 405 POST, когда пытаюсь опубликовать сообщение чата в ChatHandler. Chatscreen.html изначально отображается из ChatHander без проблем, просто когда я пытаюсь опубликовать чат, я получаю сообщение об ошибке. Спасибо за любой совет, который вы можете дать -

Вот код чата Python:

import httpagentparser
from boilerplate import models
from boilerplate.lib.basehandler import BaseHandler
from boilerplate.lib.basehandler import user_required

import cgi
import urllib
import os
import logging
import webapp2
import jinja2

from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.api import memcache

class ChatMessage(db.Model):
    user = db.StringProperty()
    text = db.StringProperty()
    created = db.DateTimeProperty(auto_now=True)

class User(db.Model):
    account = db.StringProperty()
    user = db.StringProperty()



class ChatHandler(BaseHandler):
    def get(self, **kwargs):
        params = {
        }
        return self.render_template('chatscreen.html', **params)

    def post(self, **kwargs):
        user = self.request.get('user')
        self.session['user'] = user

        if not 'user' in self.session:
            params = {
            'error' : 'Must be logged in'
            }
            return self.render_template('chatscreen.html', **params) 
            return

        msg = self.request.get('message')
        if msg == '':
           params = {
           'error' : 'Blank message ignored'
           }
           return self.render_template('chatscreen.html', **params)           
           return

        newchat = ChatMessage(user = "temp_user3", text=msg)
        newchat.put(); 
        if newchat.put():
            chat_list = ChatMessage.all().order('-created').fetch(100)  #pulling chat messages to include new ones not yet in memcache 
            memcache.set('chat_list_key', chat_list, time=2000000)       
            logging.info('entry added by user -- memcache & datastore updated with new list')       

        params = {
        }
        return self.render_template('chatscreen.html', **params)    

class MessagesHandler(BaseHandler):            
    def get(self, **kwargs):
        chat_list = memcache.get('chat_list_key')   #checking cache for chat_list    

        # if no chat_list then pull a list from datastore and populate memcache 
        if chat_list is None:
            chat_list = ChatMessage.all().order('-created').fetch(100) 
            memcache.set('chat_list_key', chat_list, time=2000000)
            logging.info('Saving chat_list to memcache *** no messages found')
            params = {
            'chat_list': chat_list
            }
            return self.render_template('messagelist.html', **params) 

        #if chat_list exist then pull data from memcache
        else: 
            params = {
            'chat_list': chat_list
            }
            return self.render_template('messagelist.html', **params)
            logging.info('Got chat_list from cache')    

class MainHandler(BaseHandler):
    def get(self):
        user = self.session.get('user')
        params = {
        'user': user
        }
        return self.render_template('index.html', **params) 

Вот маршрутизация:

from webapp2_extras.routes import RedirectRoute
from web import handlers
secure_scheme = 'https'

_routes = [
    RedirectRoute('/chat/', handlers.ChatHandler, name='chat', strict_slash=True),
    RedirectRoute('/messages/', handlers.MessagesHandler, name='messages', strict_slash=True),
    RedirectRoute('/secure/', handlers.SecureRequestHandler, name='secure', strict_slash=True)
]

def get_routes():
    return _routes

def add_routes(app):
    if app.debug:
        secure_scheme = 'http'
    for r in _routes:
        app.router.add(r)

Вот чатскрин.html:

{% extends "_base.html" %}
{% block bodycontent %}
      <h1>AppEngine Chat</h1>
      <form method="post" action="/chat">
      <p>
      <input type="text" name="message" size="60"/>
      <input type="submit" value="Chat"/> 
      </p>
      </form>
      {% if not error == None %}
       <p>
       {{ error }} 
       </p>
      {% endif %}
      <div id="chatcontent">
          Loading...
          <!-- <img src="/static/spinning.gif" alt="Loading..."/> -->
      </div>
<script> /* <![CDATA[ */

$(document).ready(function(){
$(function() {

    updateMsg();

});

function updateMsg() {

    $('#chatcontent').load('/messages');
    setTimeout(updateMsg, 5000);

}
});//end doc.onready function
/* ]]> */
</script>
{% endblock %}

А вот messagelist.html:

{% for chat in chat_list %}
  <p>
      <strong>{{ chat.user}}</strong>: 
      <br />  {{ chat.text }} 

  </p> 
{% endfor %}

person Matt Ellis    schedule 04.06.2013    source источник


Ответы (2)


Вы проверили RedirectRoute, чтобы узнать, выполняет ли он какую-либо обработку POST, которая может вернуть эту ошибку?

РЕДАКТИРОВАТЬ: я быстро взглянул на gae-boilerplate, у него есть дополнительный код в его main.py

routes.add_routes(app)
boilerplate_routes.add_routes(app)
admin_routes.add_routes(app)

Последние две функции могут испортить ваши маршруты. Я бы рекомендовал не использовать шаблон, если вы не знаете, что он делает.

person dragonx    schedule 04.06.2013
comment
Кажется, я нигде не могу найти, что это может вызвать проблему с POST, но я действительно думаю, что вы что-то понимаете в том, что маршрутизация что-то испортила со строгой косой чертой. Когда я изменяю код, чтобы использовать только маршрут, и удаляю конечные косые черты в маршрутизации, я получаю сообщение об ошибке «Отказано в доступе к ресурсу», когда я пытаюсь опубликовать сообщение чата. - person Matt Ellis; 04.06.2013
comment
Я также пробовал использовать RedirectRoute с приложением ВНЕШНИМ шаблоном, и это сработало, когда я взял трейлинг/отключение маршрутизации чата. Итак, я попробовал это (убрал косую черту) внутри шаблонной среды с маршрутизацией с использованием RedirectRoute, но получил ошибку «Отказано в доступе к ресурсу». - person Matt Ellis; 05.06.2013

Я думаю, что понял... при вставке этого кода в шаблон я по ошибке отрезал обработчик, который имеет дело с сессиями - я считаю, что это то, что выдавало ошибку.

person Matt Ellis    schedule 06.06.2013
comment
У меня похожая проблема (POST работает без использования gae-boilerplate, но не работает при интеграции с gae-b). Я нашел еще один вопрос, stackoverflow.com/questions/13020681/, он сказал: он должен включать csrf_token во все запросы POST. Я не знаком с управлением сеансом в Интернете, знаете ли вы, что я должен добавить в свой обработчик почтовых запросов? - person 正宗白布鞋; 07.06.2013
comment
Хорошо, я найду способ. В моем случае диспетчеризация функции в basehandler в gae-b блокирует POST, если _csrf_token не совпадает... Ссылка на другие примеры форм в gae-b, и после того, как я добавлю одно скрытое поле в свою форму, ‹тип ввода =hidden name=_csrf_token value={{ csrf_token() }}›, теперь все работает нормально. - person 正宗白布鞋; 07.06.2013